劍指 Offer 61. 撲克牌中的順子

從撲克牌中隨機抽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] .

一、陣列排序

做這道題的思路:

首先要把nums進行陣列排序,然後nums[4]為最大數,nums[0]為最小數,如果最大數減去最小數小於等於4,則可以構成順子。

以下程式碼是逆序進行比較。

public class Solution {
public boolean isStraight(int[] nums) {
Arrays.sort(nums);
for (int i = 3; i >= 0; i--)
if (nums[i] == 0) return (nums[4] - nums[i + 1]) <= 4;
else if (nums[i] == nums[i + 1]) return false;
return (nums[4] - nums[0]) <= 4;
}
}

這個思路是K神的思路:

  • 先對陣列執行排序。
  • 判別重複: 排序陣列中的相同元素位置相鄰,因此可通過遍歷陣列,判斷 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;
}
return nums[4]-nums[joker] <=4;//nums[4]-nums[joker]<=4是順子,如果>=4則不是順子
}
}

二、雜湊Set

做題思路:

先把max和min初始化,然後遍歷陣列,找出最大數和最小數。要注意的就是如果HashSet找出重複的數,則返回false,否則與陣列排序的思路同理。

class Solution {
public boolean isStraight(int[] nums) {
Set<Integer> res = new HashSet<>();
int max = 0, min = 14;
for (int num : nums) {
if (num == 0) continue;
max = Math.max(max, num);
min = Math.min(min, num);
if (res.contains(num)) return false;
res.add(num);
}
return max - min <= 4;
}
}

參考連結:https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/solution/mian-shi-ti-61-bu-ke-pai-zhong-de-shun-zi-ji-he-se/