题目描述
- 题目
给定一个未排序的整数数组,找出最长连续序列的长度。
-
要求算法的时间复杂度为 O(n)。
-
示例:
输入: [100, 4, 200, 1, 3, 2] 输出: 4 解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
解题
数组形式
- 遍历整个数组,并调用函数判断与目标数连续序列的长度
- 需要对遍历过程中的重复数字进行处理,避免长度计算错误
- 循环上述步骤,直到遍历结束
代码实现
class Solution {
public:
int MaxLength(vector<int> & v,int begin){
int end=begin+1;
int start=begin;
int flag=0;
while(end<v.size()){
if(v[start]==v[end]-1 ){
start=end;
end++;
}else if(v[start]==v[end]){
//记录重复数字的个数
start=end;
end++;
++flag;
}else{
break;
}
}
return end-begin-flag;//返回的是去重之后的结果
}
int longestConsecutive(vector<int>& nums) {
if(nums.empty()){
return 0;
}
sort(nums.begin(),nums.end());
int length=0;
int index=0;
int flag=1;
while(index<nums.size()){
if(flag==1){
//该判断是为了将第一次调用函数的长度设定为最长长度
length=MaxLength(nums,index);
index+=length;
flag=0;
}else{
int max=MaxLength(nums,index);
index+=max;//更新到下一个目标数
if(max>length){
length=max;
}
}
}
return length;
}
};
改进版本
- 减少一个判断,使用了函数max();
class Solution {
public:
int MaxLength(vector<int> & v,int begin){
int end=begin+1;
int start=begin;
int flag=0;
while(end<v.size()){
if(v[start]==v[end]-1 ){
start=end;
end++;
}else if(v[start]==v[end]){
start=end;
end++;
++flag;
}else{
break;
}
}
return end-begin-flag;
}
int longestConsecutive(vector<int>& nums) {
if(nums.empty()){
return 0;
}
sort(nums.begin(),nums.end());
int length=0;
int index=0;
int flag=1;
while(index<nums.size()){
int max_len=MaxLength(nums,index);
index+=max_len;
length=max(length,max_len);
}
return length;
}
};
哈希表
- 将数组中的元素存储到哈希表中,该过程达到了去重的目的
- 开始遍历哈希表,记录其中最长连续序列的长度
在遍历的过程中,若存在比目标数小 1 1的数,则目标数不是和当连续序列的开头继续循环
若不存在比目标数小 1 的数,说明该数可以当作连续序列的开头.并计算其连续序列的长度
代码
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> st;
for(int n: nums) st.insert(n);
int ans = 0;
for(int i: st){
// 假如一个数在哈希表中存在比他小的,那么它不是可以作为开头的数字
if(i != INT_MIN && st.count(i-1)){
continue;
}
int cnt = 1;
while(i!=INT_MAX && st.count(i+1)){
//记录有序序列的长度
cnt ++;
i++;
}
ans = max(ans, cnt);
}
return ans;
}
};