LeetCode | Longest Consecutive Sequence(最长连续序列)

Given an unsorted array of integers, find the length of the longest consecutive elements sequence.

For example,
Given [100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.

Your algorithm should run in O(n) complexity.


题目解析:

方案一:

通过排序方法,很容易找到相应的连续数值。但是排序复杂度至少是O(nlogn)。不满足线性要求。


方案二:

要求线性方法,先尝试能否改变策略来求得。正如LeetCode | First Missing Positive 那样。但是很可惜,没有想到。

最常用的是空间换时间,就利用哈希映射后,再遍历的方法来求解。

先求出max和min,然后建立大小为max-min+1空间的容量,将数据映射到其中。

再遍历整个哈希数组,求出连续的最大值。很可惜,这样太浪费空间了。用c的话,没有什么好的方法。但c++有相应的容器。稍后讲解。

class Solution {
public:
    int longestConsecutive(vector<int> &num) {
        int min,max;
        int n = num.size();
        if(n == 0)
            return 0;
        min = max = num[0];
        for(int i = 1;i < n;i++){
            if(num[i] > max)
                max = num[i];
            else if(num[i] < min)
                min = num[i];
        }
        int *h = new int[max-min+1];
        for(int i = 0;i < n;i++)
            h[num[i]-min] = 1;
        int maxlen = 0;
        for(int i = 0;i < max-min+1;i++){
            int len = 0;
            while(i < max-min+1 && h[i] == 0)   //找到第一个为1的数
                i++;
            while(i < max-min+1 && h[i] == 1){  //计算连续1的个数
                i++;
                len++;
            }
            if(len > maxlen)    //更新最大值
                maxlen = len;
        }
        return maxlen;
    }
};


方案三:

C++中有set集,有的网友set<int> map; 但由于其也是插入,造成了查找时间复杂度也是logn。可以用的是unordered_set,查找时间复杂度为O(1)。找到后,先清除标记,然后相应的查找++的数,和--的数。最后求和。

class Solution{
public:
    int longestConsecutive(vector<int> &num) {
        int ans = 0;
        for(int i = 0;i < num.size();i++)
            map.insert(num[i]);
        for(int i = 0;i < num.size();i++){
            int count = findBound(num[i],true) + findBound(num[i]+1,false);
            ans = ans > count ? ans : count;
        }
    }
    int findBound(int n,bool asc){
        int count = 0;
        while(map.find(n) != map.end()){
            count++;
            map.erase(n);
            if(asc)
                n--;
            else
                n++;
        }
        return count;
    }
private:
    unordered_set<int> map;
};




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值