每日一題 - 劍指 Offer 61. 撲克牌中的順子
阿新 • • 發佈:2020-07-12
題目資訊
-
時間: 2019-07-06
-
題目連結:Leetcode
-
tag: 雜湊表 排序
-
難易程度:中等
-
題目描述:
從撲克牌中隨機抽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
注意
1. 陣列長度為 5
2. 陣列的數取值為 [0, 13]
解題思路
本題難點
順子包含'大小王'的特殊情況。
具體思路
集合 Set + 遍歷
5 張牌是順子的 充分條件:
- 除大小王外,所有牌 無重複 ;
- 設此 5張牌中最大的牌為 max ,最小的牌為 min(大小王除外),則需滿足:max − min < 5
提示
程式碼
class Solution { public boolean isStraight(int[] nums) { if(nums.length == 0 || nums == null){ return false; } HashSet<Integer> set = new HashSet<>(); int min = 13; int max = 0; for(int num : nums){ //遍歷五張牌,遇到大小王(即 0 )直接跳過。 if(num == 0){ continue; } //獲取最大 / 最小的牌: 藉助輔助變數 max 和 min ,遍歷統計即可。 min = Math.min(num,min); max = Math.max(num,max); //判別重複: 利用 Set 實現遍歷判重 if(set.contains(num)){ return false; } set.add(num); } return max - min < 5; } }
複雜度分析:
- 時間複雜度 O(N) : 其中 N為 nums長度,本題中 N=5 ;遍歷陣列使用 O(N)時間。
- 空間複雜度 O(N) : 用於判重的輔助 Set 使用 O(N)額外空間。
其他優秀解答
解題思路
先對陣列執行排序。
判別重複: 排序陣列中的相同元素位置相鄰,通過遍歷陣列,判斷 nums[i]=nums[i+1] 是否成立來判重。
獲取最大 / 最小的牌: 排序後,陣列末位元素 nums[4] 為最大牌;元素 nums[joker] 為最小牌,其中 joker 為大小王的數量。
程式碼
class Solution { public boolean isStraight(int[] nums) { int joker = 0; Arrays.sort(nums); // 陣列排序 for(int i = 0; i < 4; i++) { if(nums[i] == 0) joker++; // 統計大小王數量 else if(nums[i] == nums[i + 1]) return false; // 若有重複,提前返回 false } return nums[4] - nums[joker] < 5; // 最大牌 - 最小牌 < 5 則可構成順子 } }