每日一練(33):撲克牌中的順子

加班猿發表於2022-03-15

title: 每日一練(33):撲克牌中的順子

categories:[劍指offer]

tags:[每日一練]

date: 2022/03/08


每日一練(33):撲克牌中的順子

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

來源:力扣(LeetCode)

連結:https://leetcode-cn.com/probl...

方法一:不排序方式

演算法流程:

1、5 張撲克牌中的最大值 maxValue 和最小值 minValue ,那我們就知道,要使它為順子需要 maxValue - minValue + 1 張牌。

在查詢 maxValue 和 minValue 過程中,跳過大小王 0 。

如果 maxValue - minValue + 1 > 5,說明題目給的 5 張牌不足以構成順子,返回 false .

  • 即使裡面有大小王,也不夠用來填補使它構成順子。

如果 maxValue - minValue + 1 <= 5,說明 5 張牌足以構成順子,返回 true。

  • 裡面的大小王填補在合適位置即可。

2、同時,我們再定義一個標誌陣列判斷是否有重複數字,發現重複數字直接返回 false 即可。

bool isStraight(vector<int>& nums) {
    bool m[15];
    memset(m, 0, sizeof(m));
    int minValue = 14, maxValue = 0;
    for (int item : nums) {
        if (item == 0) {
            continue;
        }
        if (m[item]) {
            return false;
        }
        m[item] = true;
        minValue = min(minValue, item);        
        maxValue = max(maxValue, item);
    }
    return (maxValue - minValue + 1 <= 5);
}

方法二:排序方式

演算法流程:

排序之後撲克牌就有序了,我們就可以直接判斷相鄰兩張牌之間需要多少個大王或小王來填補。

  • 如果需要填補大小王的數量,大於已有大小王的數量,則返回 false
  • 相反,如果需要填補大小王的數量,小於或等於已有大小王的數量,則返回 true
bool isStraight(vector<int>& nums) {
    sort(nums.begin(), nums.end());    //排序
    int zero = 0;
    for (int i = 0; i < 4; i++) {
        if (nums[i] == 0) {    //計數大小王
            zero++;
            continue;
        }
        if (nums[i] == nums[i+1]) {//有重複
            return false;
        }
        zero -= nums[i+1] - nums[i] - 1;//需要填補大小王的數量
    }
    return zero >= 0;
}

相關文章