你們可能不知道只用 20 萬贏到 578 萬是什麼概念。 我們一般只會用兩個字來形容這種人:賭怪! 我經常說一句話,當年陳刀仔他能用 20 塊贏到 3700 萬,我 LBW 用 20 萬贏到 500 萬不是問題。 埋伏他一手,這個牌不能搶,這個牌不用搶,他死定了。 反手給一個超級加倍,悶聲發大財。他也超級加倍?但是不用怕,他的牌贏不了我。 五六七八九十,兩個炸,很牛逼這個牌,如果把這個 K 換成 J ,我這個牌將絕殺,但是換不得。 單走一個六,SB,直接把 K 走了。 走他一張 2 頂他。阿姨快點,阿姨,阿姨你 K 都不要嗎?阿姨你快點啊!阿姨別磨磨蹭蹭的。 五六七八九十。打錯了,應該打 2 的。 給阿姨倒杯茶好吧,阿姨給你倒一杯卡布奇諾。 給阿姨倒一杯卡布奇諾!開始你的炸彈秀,炸他炸他。漂亮! 十七張牌你能秒我?你能秒殺我?!你今天能十七張牌把盧本偉秒了,我!當!場!就把這個電腦屏幕喫掉!!!
題目鏈接
LeetCode 846. 一手順子[1]
題目描述
愛麗絲有一手(hand)由整數數組給定的牌。
現在她想把牌重新排列成組,使得每個組的大小都是 W
,且由 W
張連續的牌組成。
如果她可以完成分組就返回 true
,否則返回 false
。
說明:
-
1 <= hand.length <= 10000
-
0 <= hand[i] <= 10^9
-
1 <= W <= hand.length
示例1
輸入:
hand = [1,2,3,6,2,3,4,7,8], W = 3
輸出:
true
解釋:
愛麗絲的手牌可以被重新排列爲 [1,2,3],[2,3,4],[6,7,8]。
示例2
輸入:
hand = [1,2,3,4,5], W = 4
輸出:
false
解釋:
愛麗絲的手牌無法被重新排列成幾個大小爲 4 的組。
題解
巧用 map
這也是最直觀的一個方法,用 map
來保存每個數出現的次數。
然後從最小的數開始,以它作爲順子的開頭,然後看順子裏的數在不在 map
裏,在就次數減一,不在就直接返回 false
。
接着重複上面步驟,最後直到 map
爲空,最後返回 true
。
map
的特性就是你取它的第一個鍵值對,它的 key
就是最小的,這就很方便了。
排序統計
首先對手牌從小到大進行排序,然後從最小的開始,作爲順子開頭,遍歷之後的數。如果在數組裏,並且沒有被訪問過,那麼就標記爲訪問過了。
注意可以提前終止遍歷,也就是如果發現某一個順子還沒遍歷完,但是訪問到的元素已經超過接在順子後的數了,那就直接返回 false
。
排序統計2
這題還有個解法,來自於題解區網友 zhanzq
,感覺挺不錯的。但是我沒怎麼看懂,如果誰看懂了請教教我。
網友題解[2]
代碼
巧用 map(c++)
class Solution {
public:
bool isNStraightHand(vector<int>& hand, int W) {
int n = hand.size();
if (n%W) return false;
map<int, int> count;
for (auto x : hand) count[x]++;
while (count.size()) {
int start = count.begin()->first;
for (int i = start; i < start+W; ++i) {
if (count.find(i) == count.end()) return false;
if (!--count[i]) count.erase(i);
}
}
return true;
}
};
排序統計(c++)
class Solution {
public:
bool isNStraightHand(vector<int>& hand, int W) {
int n = hand.size();
if (n%W) return false;
if (W==1) return true;
sort(hand.begin(), hand.end());
vector<int> vis(n, 0);
for (int i = 0; i < n; ++i) {
if (vis[i]) continue;
int cnt = 1;
vis[i] = 1;
for (int j = i+1; j < n; ++j) {
if (hand[j]>hand[i]+cnt) break;
if (!vis[j] && hand[j]==hand[i]+cnt) {
vis[j] = 1;
cnt++;
if (cnt == W) break;
}
}
if (cnt != W) return false;
}
return true;
}
};
排序統計2,來自於網友zhanzq(c++)
class Solution {
public:
bool valid(vector<int> &lst, int W){
lst.push_back(0);
int sz = lst.size();
int pre = 0;
vector<int> deltas(sz, 0);
for(int i = 0; i < sz; i++){
pre += deltas[i];
if(pre < lst[i]){
int delta = lst[i] - pre;
pre = lst[i];
if(i + W < sz){
deltas[i+W] -= delta;
}
}else if(pre > lst[i]){
return false;
}
}
return true;
}
bool isNStraightHand(vector<int>& hand, int W) {
int sz = hand.size();
if(sz%W){
return false;
}else{
sort(hand.begin(), hand.end());
vector<int> lst;
int i = 0, j = 0;
while(i < sz){
while(j < sz && hand[i] == hand[j]){
j++;
}
lst.push_back(j - i);
if(j >= sz){
break;
}else if(hand[j] != hand[j-1] + 1){
lst.push_back(0);
}
i = j;
}
return valid(lst, W);
}
}
};
參考資料
[1]
LeetCode 846. 一手順子: https://leetcode-cn.com/problems/hand-of-straights/
[2]
網友題解: https://leetcode-cn.com/problems/hand-of-straights/solution/onlognsuan-fa-by-zhanzq/