You are given an integer array sorted in ascending order (may contain duplicates), you need to split them into several subsequences, where each subsequences consist of at least 3 consecutive integers. Return whether you can make such a split.
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
Example 3:
Input: [1,2,3,4,4,5]
Output: False
数组中给出几个数,让把这些数划分成几个子序列,每个子序列中至少是3个连续的数字,可以多于3个,但是数字必须是连续的
思路:
每个数字要么自己开头创造一个新的子序列,要么接在现有子序列的后面
如果自己创造一个新的子序列,假设这个数是x,因为要求子序列中必须至少有3个连续的数字,所以x+1, x+2必须存在而且没有被其他子序列用完(使用次数>0)
如果接在现有子序列后面,还是假设这个数是x,那么x+1应该也可以接在这个后面,同时要把自己的使用次数-1
因为涉及到了使用次数,所以要保存每个数字对应的频率,所以用一个HashMap
同时如何判断是否能接在现有子序列后面,能接在多少个子序列后面,也是需要一个HashMap,保存一个可以接在现有子序列后面的数字及能接的子序列的个数
如果即不能接在现有子序列后面,又不能开创新子序列,直接返回false
**注意follow这个HashMap,刚开始的时候并没有保存可以接在子序列后面的数字,所以hashMap.get时,如果数字不存在,返回的是null而不是0,所以要用getOrDefault
public boolean isPossible(int[] nums) {
if (nums == null || nums.length < 3) {
return false;
}
HashMap<Integer, Integer> freq = new HashMap<Integer, Integer>();
HashMap<Integer, Integer> follow = new HashMap<Integer, Integer>();
for (int num : nums) {
freq.put(num, freq.getOrDefault(num, 0) + 1);
}
for (int num : nums) {
if (freq.get(num) == 0) { //already used..
continue;
}
if (follow.getOrDefault(num, 0) > 0) { //follow as a subsequnce..
follow.put(num, follow.get(num) - 1);
follow.put(num + 1, follow.getOrDefault(num + 1, 0) + 1);
} else { //start by self..
if (freq.getOrDefault(num + 1, 0) > 0 && freq.getOrDefault(num + 2, 0) > 0) {
freq.put(num + 1, freq.get(num + 1) - 1);
freq.put(num + 2, freq.get(num + 2) - 1);
follow.put(num + 3, follow.getOrDefault(num + 3, 0) + 1);
} else {
return false;
}
}
freq.put(num, freq.get(num) - 1);
}
return true;
}