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;
}