LeetCode 128最长连续序列Hard
- 题目简述:给定一个未排序的整数数组,找出最长连续序列的长度。要求算法的时间复杂度为 O(n)。
- 输入:[100, 4, 200, 1, 3, 2] 输出:4 解释:最长连续序列是 [1, 2, 3, 4]
- 思路:双指针算法
- 首先对未排序的数组进行排序,并将双指针都指向开始位置
- 只要
r
指向的数字等于r-1
指向的数字或者比r-1
指向的数字大1
,那么r
指针就向右移动扩大窗口,在移动过程中,当r
指向的数字等于r-1
指向的数字时,长度不变;当r
指向的数字大r-1
指向的数字1
时,长度增加。 - 如果发现
r
指向的数字不连续了,将r
作为l
的新起点重新开始窗口滑动
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
if(nums.empty()) return 0;
sort(nums.begin(), nums.end());
int l = 0, r = 0, ans = 0;
while(l <= r && l < nums.size() && r < nums.size())
{
r = l + 1;
int count = 1;
while(r < nums.size() && (nums[r] == nums[r - 1] || nums[r] == nums[r - 1] + 1))
{
if(nums[r] == nums[r - 1] + 1) count ++;
r++;
}
ans = max(ans, count);
l = r;
}
return ans;
}
};
-
思路:哈希表去重
将数组存入去重的哈希表中,只需要枚举每一个数尝试作为连续序列的起点,如果一个数是
x
,那么当它的前一个数x - 1
不在哈希表中时,则该数就可能是一个新连续序列的起点,然后尝试查找x+1、x+2...x+n
是否在哈希表中,只要遇到某个数不连续了就更新答案。
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> hash(nums.begin(), nums.end());
int ans = 0;
for(auto &x : nums)
{
if(!hash.count(x - 1))
{
int cur = 1;
while(hash.count(x + cur)) cur++;
ans = max(ans, cur);
}
}
return ans;
}
};
- 思路三:
- 哈希表记录每个点以及该点为边界的最大长度,这里只有区间端点的值才是真正的区间长度,而区间内部的的点的值仅起到记录该点出现过的意义。如果当前扫描到的数已经在哈希表中了,则直接跳过。
- 当扫描到一个新数字时,找该数字左右数字的最大长度,合并后,更新该数字和新连续序列左右数字的哈希值。当遍历到
x
时,先求出x−1
的最大长度,则由于x
第一次遍历到,所以x−1
如果存在,则一定是某个区间的右端点,同理x+1
一定是某个区间的左端点。
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
int ans = 0;
unordered_map<int, int> hash;
for(auto &x : nums)
{
if(hash[x]) continue; //如果当前扫描到的数已经在哈希表中了,则直接跳过。
hash[x] = 1; //标记出现
int left = hash[x - 1];//记录左右点包含的点个数
int right = hash[x + 1];
hash[x - left] = right + left + 1;//更新左右边界区间内点的个数
hash[x + right] = right + left + 1;
ans = max(ans, right + left + 1);
}
return ans;
}
};