Given an array nums
sorted in ascending order, return true
if and only if you can split it into 1 or more subsequences such that each subsequence consists of consecutive integers and has length at least 3.
Example 1:
Input: [1,2,3,3,4,5] Output: True Explanation: You can split them into two consecutive subsequences : 1, 2, 3 3, 4, 5
Example 2:
Input: [1,2,3,3,4,4,5,5] Output: True Explanation: You can split them into two consecutive subsequences : 1, 2, 3, 4, 5 3, 4, 5
思路:用greedy,先统计频率,再用一个urgentTail hashmap来统计我即将需要的下一个数的频率,这题巧妙的思考就是数字是否使用过,是用count来标记的,用过就减一,下次判断的时候,看是否还有count,没有了,就代表不能再用了,被之前的用过了。
另外greedy的思想就是:每遇见一个数,如果还可以用,首先考虑urgentmap里面是否有人需要这个数,需要就加进去,并且同时加入下一个需要的数,这就是贪心,然后如果没有人需要,就开启一个3顺子,如果不能开启,代表不行,能开启,三个数频率-1,同时加入urgentmap下一个数;
class Solution {
public boolean isPossible(int[] nums) {
if(nums == null || nums.length == 0) {
return false;
}
HashMap<Integer, Integer> frequencyMap = new HashMap<>();
HashMap<Integer, Integer> urgentTail = new HashMap<>();
for(Integer i: nums) {
frequencyMap.put(i, frequencyMap.getOrDefault(i, 0) + 1);
}
for(Integer i: nums) {
// 用count -1 代表已经用过了;如果还有没有用的,count number > 0;
if(frequencyMap.get(i) <= 0) {
continue;
}
// Greedy,首先满足已经有的顺子的尾巴,并且加入新的尾巴;
if(urgentTail.getOrDefault(i, 0) > 0) {
frequencyMap.put(i, frequencyMap.get(i) - 1);
urgentTail.put(i, urgentTail.get(i) - 1);
// Greedy, 把下一个也加进去;
urgentTail.put(i + 1, urgentTail.getOrDefault(i + 1, 0) + 1);
} else {
// 开始一个顺子:i, i + 1, i + 2;
if(frequencyMap.getOrDefault(i + 1, 0) > 0
&& frequencyMap.getOrDefault(i + 2, 0) > 0) {
frequencyMap.put(i, frequencyMap.get(i) - 1);
frequencyMap.put(i + 1, frequencyMap.get(i + 1) - 1);
frequencyMap.put(i + 2, frequencyMap.get(i + 2) - 1);
urgentTail.put(i + 3, urgentTail.getOrDefault(i + 3, 0) + 1);
} else {
// 没有超过3个的顺子;
return false;
}
}
}
return true;
}
}