此题难就难在数组为排序且时间复杂度在o(n)
注意此题目中如果数列[2,2,3]这样的数组,连续的数为[2,3]
思路:
1、如果给我们一个数组 我们可能会这样做:先取第一个元素,假如是k。 然后查找数组是否有k-1和k+1这两个数,然后递归查找。查找完后把当前数以及找到的其他连续的数删除。重复下去,可知每个数最多遍历一次,所以时间复杂度为o(n),判断数组众是否存在某个数可借助hash_map实现(这里注意:c++ stl中的map是红黑树实现的排序map,查找复杂度为o(lgn) unordered_map查找为o(n))
2、但是写链表的话比较复杂,这里借鉴了大佬的代码 感觉真的很牛逼。
这里的Map不是预先保留某个数的存在信息。这里一个连续序列的长度是由序列的开头和结尾元素保存.如[1,2,3,4,5] m[1]=5=m[5]。为什么只用保存边界呢,因为你对一个数查找时只会找他的前一个数和后一个数,而此时这个数没有在map中因此他的前一个数和后一个数必然是某个已经存在的有序序列的边界y,记左边界为left 右边界为right 则新的序列的长度为left+right+1,更新边界值。
代码:
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_map<int,int> m;
int ans=0;
for(int i=0;i<nums.size();i++){
if(m.find(nums[i])==m.end()){
int left=m.find(nums[i]-1)==m.end()? 0:m[nums[i]-1];
int right=m.find(nums[i]+1)==m.end()? 0:m[nums[i]+1];
int length=left+right+1;
ans=max(ans,length);
m[nums[i]]=m[nums[i]-left]=m[nums[i]+right]=length;
}
}
return ans;
}
};