1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public boolean isNStraightHand(int[] hand, int groupSize) {
TreeMap<Integer, Integer> cardFreq = new TreeMap<>();
for (int card : hand) {
cardFreq.put(card, cardFreq.getOrDefault(card, 0) + 1);
}
while (!cardFreq.isEmpty()) {
int lowest = cardFreq.firstKey();
for (int i = 0, currNum = lowest; i < groupSize; i++) {
if (!cardFreq.containsKey(currNum) || cardFreq.get(currNum) <= 0) {
return false;
}
cardFreq.put(currNum, cardFreq.get(currNum) - 1);
if (cardFreq.get(currNum) <= 0) {
cardFreq.remove(currNum);
}
currNum += 1;
}
}
return true;
}
}

思路就是把所有元素的freq统计一下, 然后从小到大开始遍历. 如果要把最小的元素都抵消完, 那么往上找数字和最小元素构成groupsize的一组. 其中的数字的freq必须都比最小元素的freq大于等于才行, 否则最小的元素就不能被抵消完. 以此类推.

比较聪明的一点就是我们从当前group中的最后一个元素开始遍历, 比较它的freq和当前group中最小元素的freq. 因为如果从小到大遍历的话, 我们一更新换代最小元素的freq为0, 后面的元素就不知道最小元素的freq是多少了, 我们还要额外地去存. 因此第9行是倒着遍历的.

时间复杂度: O(nlogn) 放到treemap里面的时候需要O(nlogn), 遍历是O(n).
空间复杂度: O(n) 因为用到了map.