1. 程式人生 > 實用技巧 >劍指Offer_#61_撲克牌中的順子

劍指Offer_#61_撲克牌中的順子

劍指Offer_#61_撲克牌中的順子

劍指offer

Contents

題目

從撲克牌中隨機抽5張牌,判斷是不是一個順子,即這5張牌是不是連續的。2~10為數字本身,A為1,J為11,Q為12,K為13,而大、小王為 0 ,可以看成任意數字。A 不能視為 14。

示例1:
輸入: [1,2,3,4,5]
輸出: True
示例2:
輸入: [0,0,1,2,5]
輸出: True

限制:
陣列長度為 5
陣列的數取值為 [0, 13] .

思路分析

順子的判斷方法

一個連續的陣列是否是順子,需要滿足兩個條件。
條件1:沒有重複牌
除了0之外,5個數字當中沒有對子,即沒有相同的兩個牌。
條件2:0可以補齊缺失的牌

  1. 0的個數 ≥ 間隔的個數。間隔指的是連續數字中缺失的那些數字,這些數字可以由0來補齊。
  2. max - min <= 4
    • 如果最大值和最小值差距大於4,那麼連續陣列的長度一定大於5,但是輸入陣列只有5個數字,那麼必定存在漏掉的數字,不可能是連續的。
    • 對於連續的5個數字,最大值和最小值之間剛好相差4。最大值和最小值差距小於4時,[min...max]之間的數字個數少於5個,min和max之外剩下的數字只有可能是0或者min
      max之間的數,一定可以構成一個連續陣列。

方法1:比較0的個數與間隔個數

  1. 排序,0必然出現在最前面
  2. 遍歷陣列,統計間隔的數量及0的數量
    • 遍歷過程中發現相同的數,直接返回false
  3. 比較0的個數和間隔的個數,0的個數如果大於等於間隔的個數,返回true,否則返回false

方法2:HashSet方法

  • max - min <= 4,如果是5張連續牌,最大與最小牌的差距最多到4。即需要統計最大牌和最小牌,通過迴圈遍歷實現。這個方法避免了統計缺失的數字,還有0的個數。
  • 出現對子,直接返回false。所以需要判別重複。想到用Set資料結構,可以最快的找出重複,避免了排序。
    • Set<Integer> set = new HashSet<>();

解答

解答1:比較0的個數和間隔的個數

class Solution {
    public boolean isStraight(int[] nums) {
        //1.排序,0必然出現在最前面
        Arrays.sort(nums);
        int numberOfZero = 0;
        int numberOfGap = 0;
        //2.遍歷陣列,統計間隔的數量及0的數量
        for(int i = 0;i <= 4;i++){
            if(nums[i] == 0) numberOfZero++;
        }
        for(int i = numberOfZero;i <= 3;i++){
            //出現一對相同數,不可能是順子
            if(nums[i] == nums[i + 1]) return false;
            numberOfGap += nums[i+1] - nums[i] - 1;
        }
        return numberOfZero >= numberOfGap;
    }
}

複雜度分析

時間複雜度:O(nlogn),排序的複雜度是O(nlogn)
空間複雜度:O(1)

解答2:利用HashSet判斷重複

class Solution {
    public boolean isStraight(int[] nums) {
        Set<Integer> set = new HashSet<>();
        //注意max和min的初始化,max要初始化為比最小值1還小的0,min要初始化為比最大的13還大的14
        //目的是:進入迴圈後,一開始就會更新
        int max = 0;
        int min = 14;
        for(int i = 0;i <= 4;i++){
            //0不統計在內
            if(nums[i] == 0) continue;
            //更新最大值和最小值
            max = Math.max(max, nums[i]);
            min = Math.min(min, nums[i]);
            if(set.contains(nums[i])) return false;
            set.add(nums[i]);
        }
        return max - min <= 4;
    }
}

複雜度分析

時間複雜度:O(n)
空間複雜度:O(n)