解法都在代码里,不懂就留言或者私信
class Solution {
/**第一种解法基于TreeMap */
public boolean isNStraightHand2(int[] hand, int groupSize) {
/**首先我们得能平均分成groupSize才行,不能分绝对不行 */
if(hand == null || hand.length < groupSize || hand.length % groupSize != 0) {
return false;
}
/**能均分的情况下我们统计一下每个数字出现了多少次,这里因为数字很大,就用hash表吧,用数组代替哈希表会很浪费空间*/
TreeMap<Integer,Integer> countMap = new TreeMap<>();
for(int num : hand) {
countMap.put(num, countMap.getOrDefault(num, 0) + 1);
}
while(!countMap.isEmpty()) {
/**我们基于当前数需要往后找多少个连续的数 */
int count = groupSize - 1;
/**先拿现在所有数里最小的那个 */
int min = countMap.firstKey();
/**我们要看看从min开始的连续的groupsize个数是不是都在map里 */
while(count > 0) {
/**检查的时候发现从min开始的groupSize个数有一个不在的直接返回false */
if(!countMap.containsKey(min + count)) {
return false;
}
/**如果在的话就数量减一,如果减完是0了删除 */
if(countMap.get(min + count) == 1) {
countMap.remove(min + count);
} else {
countMap.put(min + count, countMap.get(min + count) - 1);
}
count --;
}
/**以它开头的凑够了groupsize个,它也用掉了一个,数量减1,如果减成0就删除 */
if(countMap.get(min) == 1) {
countMap.remove(min);
} else {
countMap.put(min, countMap.get(min) - 1);
}
}
return true;
}
/**第二种解法基于HashMap */
public boolean isNStraightHand(int[] hand, int groupSize) {
/**首先我们得能平均分成groupSize才行,不能分绝对不行 */
if(hand == null || hand.length < groupSize || hand.length % groupSize != 0) {
return false;
}
/**这里一定要先排序 */
Arrays.sort(hand);
/**能均分的情况下我们统计一下每个数字出现了多少次,这里因为数字很大,就用hash表吧,用数组代替哈希表会很浪费空间*/
TreeMap<Integer,Integer> countMap = new TreeMap<>();
for(int num : hand) {
countMap.put(num, countMap.getOrDefault(num, 0) + 1);
}
/**再次遍历数组 */
for(int num : hand) {
/**数字我们用完了是要删除的,这个数有可能被前面某个数找连续的groupSize个数的时候用过了,用完了是要删除的*/
if(!countMap.containsKey(num)) {
continue;
}
/** 既然num存在,那我们就必须要用它了,并且它后面一直到num+groupSize-1个连续的数也必须存在
这里i写成从0开始是为了用完之后删除当前的num*/
for(int i = 0; i < groupSize; i++) {
/**如果不存在直接return false就行了 */
if(!countMap.containsKey(num + i)) {
return false;
}
countMap.put(num + i, countMap.get(num+i) - 1);
if(countMap.get(num + i) == 0) {
countMap.remove(num + i);
}
}
}
return true;
}
}