LeetCode 面试题☞最长连续序列

题目描述

  • 题目

给定一个未排序的整数数组,找出最长连续序列的长度。

  • 要求算法的时间复杂度为 O(n)。

  • 示例:

      输入: [100, 4, 200, 1, 3, 2]
      输出: 4
      解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
    

解题

数组形式
  • 遍历整个数组,并调用函数判断与目标数连续序列的长度
  • 需要对遍历过程中的重复数字进行处理,避免长度计算错误
  • 循环上述步骤,直到遍历结束

image.png

代码实现
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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值