代码题(20)— 最长连续序列
1、128. 最长连续序列
给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
示例:
输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
方法1:
这道题要求求最长连续序列,并给定了O(n)复杂度限制,我们的思路是,使用一个集合set存入所有的数字,
然后遍历数组中的每个数字,如果其在集合中存在,那么将其移除,
然后分别用两个变量pre和next算出其前一个数跟后一个数,然后在集合中循环查找,
如果pre在集合中,那么将pre移除集合,然后pre再自减1,
直至pre不在集合之中,对next采用同样的方法,那么next-pre-1就是当前数字的最长连续序列,更新res。
class Solution { public: int longestConsecutive(vector<int>& nums) { if(nums.empty()) return 0; int res = 0; unordered_set<int> s(nums.begin(), nums.end()); for(int i=0;i<nums.size();++i) { if(!s.count(nums[i])) continue; s.erase(nums[i]); int pre = nums[i] - 1; int next = nums[i] + 1; while(s.count(pre)) s.erase(pre--); while(s.count(next)) s.erase(next++); res = max(res, next-pre-1); } return res; } };
方法2:
我们也可以采用哈希表来做,刚开始哈希表为空,然后遍历所有数字,如果该数字不在哈希表中,那么我们分别看其左右两个数字是否在哈希表中,如果在,则返回其哈希表中映射值,若不在,则返回0,然后我们将left+right+1作为当前数字的映射,并更新res结果,然后更新d-left和d-right的映射值
class Solution { public: int longestConsecutive(vector<int>& nums) { if(nums.empty()) return 0; int res = 0; unordered_map<int, int> m; for(int val : nums) { if(m.count(val)) continue; int left = m.count(val-1) ? m[val-1] : 0; int right = m.count(val+1) ? m[val+1] : 0; int sum = left + right +1; m[val] = sum; res = max(res, sum); m[val-left] = sum; // 将该序列的头尾 都设置为最大长度; m[val+right] = sum; } return res; } };