- 对于涉及连续整数的问题,应该条件反射想到排序
- 想把
nums
的元素划分到若干个子序列,就是如下代码逻辑:
for(int v : nums){
if(...){
//将v分配到某个序列中
}else{
//实在无法分配v
return false;
}
return true;
}
然后对v
进行分配,总共有如下两种情况:
- 当前
v
自成一派,[以自己开头]可构成一个长度至少为3的序列。 - 当前元素
v
接到已经存在的子序列后面
如果这两种情况都满足,哪种情况需要优先考虑呢?
比如说,输入nums = [1,2,3,4,5,5,6,7]
,对于元素4
,你说它应该形成一个新的子序列[4,5,6]
还是接到子序列[1,2,3]
后面呢?
显然,nums数组的正确划分方法是分成[1,2,3,4,5]
和[5,6,7]
,所以元素4
应该优先判断自己是否能够接到其他序列后面,如果不行,再判断是否可以作为新的子序列开头。
这就是整体的思路,想让算法代码实现这两个选择,需要两个哈希表来做辅助:
freq
哈希表帮助一个元素判断自己是否能够作为开头,need
哈希表帮助一个元素判断自己是否可以被接到其他序列后面。
class Solution {
public:
bool isPossible(vector<int>& nums) {
unordered_map<int, int> freq, need;
for(int v : nums) freq[v]++;
for(int v : nums){
if(freq[v] == 0){
//已经被用到其它子序列中
continue;
}
//优先判断v是否能接到其它子序列后面,如果不行,再判断是否能够接到其它序列后面
if(need.count(v) && need[v] > 0){
//若可以
freq[v]--;
need[v]--;
need[v+1]++;
}
else if(freq[v] > 0 && freq[v + 1] > 0 && freq[v + 2] > 0){
freq[v]--;
freq[v + 1]--;
freq[v + 2]--;
need[v + 3]++;
}
else
return false;
}
return true;
}
};