846. Hand of Straights 一手顺子
作者: 负雪明烛 id: fuxuemingzhu 个人博客: https://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/hand-of-straights/description/
Alice has a hand of cards, given as an array of integers.
Now she wants to rearrange the cards into groups so that each group is size W, and consists of W consecutive cards.
Return true if and only if she can.
Example 1:
Input: hand = [1,2,3,6,2,3,4,7,8], W = 3Output: trueExplanation: Alice's hand can be rearranged as [1,2,3],[2,3,4],[6,7,8].Example 2:
Input: hand = [1,2,3,4,5], W = 4Output: falseExplanation: Alice's hand can't be rearranged into groups of 4.Note:
- 1 <= hand.length <= 10000
- 0 <= hand[i] <= 10^9
- 1 <= W <= hand.length
给出了一堆扑克牌,也给出了一个数字W,看这堆扑克牌能不能恰好全部拼成长度为W的顺子。
这个思路可以说很暴力了。先做个统计,得出手里都有哪些牌,然后找出最小的牌,从这个牌开始长度为W的遍历,判断能否构成长度为W的顺子,就这样求下去即可,直到所有的牌都结束。
做了一个优化的地方,找出最小的牌的个数,因为这个最小的牌只能和比它大的牌构成顺子,所以我们可以在遍历的时候把后面的牌的个数全部剪掉这个数字。
代码如下:
class Solution(object): def isNStraightHand(self, hand, W): """ :type hand: List[int] :type W: int :rtype: bool """ cards = collections.Counter(hand) while cards: start = min(cards.keys()) start_val = cards[start] for card in range(start, start + W): if card not in cards: return False cards[card] -= start_val if cards[card] == 0: cards.pop(card) elif cards[card] < 0: return False return not cards同样的做法,如果提前做一个排序还是能加快这个运算的,这样就不用每次都去求min了。里面用到的一个技巧是range(W)之后做了一个翻转,也就是说先从大的值开始减,这样能保证cards[start]不受干扰。
class Solution(object): def isNStraightHand(self, hand, W): """ :type hand: List[int] :type W: int :rtype: bool """ cards = collections.Counter(hand) for start in sorted(cards): if cards[start] > 0: for j in range(W)[::-1]: if start + j not in cards: return False cards[start + j] -= cards[start] if cards[start + j] < 0: return False return True用C++刷题的时候,使用Map保存每个数字的数量,因为map是自动排好序的。所以少了排序的步骤。统计个数之后,直接进行遍历,对于每个数字都向他后面搜索W - 1个数字。方法比较直白。
class Solution {public: bool isNStraightHand(vector<int>& hand, int W) { map<int, int> count; for (int h : hand) { ++count[h]; } for (auto c : count) { int cur = c.first; int n = c.second; if (n > 0) { for (int i = 1; i < W; ++i) { if (!count.count(cur + i)) { return false; } count[cur + i] -= n; if (count[cur + i] < 0) return false; } } } return true; }};2018 年 9 月 8 日 —— 美好的周末,从刷题开始 2019 年 2 月 27 日 —— 二月就要完了

评论与交流