这道题目也写得非常痛苦,还是在借鉴别人的思路下完成,极其不爽。完全不在状态。
犯了两个比较蛋疼的错误
(1)递归依然没想清楚,把core写在了后面,导致了重复计算;
(2)对状态值的更新有误,应该更新序列两端的值而不是中间的!
另外实现整体看起来非常的丑
有经验的人都说想清楚了在动笔错误就会少,我想说TMD,如果想不清楚呢?就永远不动手写?没有人能做到真正的想清楚,除非那个问题很简单。我们总是在错误中吸收教训,无视这个人往往就是那个给你传递经验的人。
class Solution {
public:
void core(vector<int> &num,int len,unordered_map<int,int> &memo,int &maxv){
if(len==0) {memo[num[len]]=1;return;}
core(num,len-1,memo,maxv);
if(memo.find(num[len])!=memo.end()) return;
//core写在这里就会让上面的if失去意义
int left=0,right=0;
if(memo.find(num[len]-1)!=memo.end()) left=memo[num[len]-1];
if(memo.find(num[len]+1)!=memo.end()) right=memo[num[len]+1];
memo[num[len]]=left+right+1;
if(maxv<memo[num[len]]) maxv=memo[num[len]];
//下面的memo如果更新的是num[len]-1则序列两端的值没有更新,更无法在下次递归时更新
if(left!=0) memo[num[len]-left]=left+right+1;
if(right!=0)memo[num[len]+right]=left+right+1;
return;
}
int longestConsecutive(vector<int> &num) {
int len=num.size();int maxv=1;
if(len==0) return 0;
unordered_map<int,int> memo;
core(num,len-1,memo,maxv);
//for(auto m:memo)
// if(m.second>maxv) maxv=m.second;
return maxv;
}
};
因为需要递归N次,每次都是常量的复杂度,总的算法时间复杂度O(N),空间复杂度也是O(N)。