128. 最长连续序列

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

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

示例:

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

方法一: 哈希表

  找到一个可以作为起点的数字(没有比它小的数),计算以它开头的最长连续子序列,如比当前记录的都长,则更新当前最长记录

 
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;
    }
};

 

方法二: 并查集

将连续的数字作为一个集合
那么扫描到一个数字,只要将它和它的下一个数字(假如存在)merge在一个集合即可。同时更新这个集合的元素个数
如果当前经过merge的集合的元素个数比当前记录的最长序列的长度都长,则更新当前最长记录

class Solution {
public:
    // cnt用于记录当前集合的元素个数
    unordered_map<int,int> uf, cnt;

    int find(int i){
        return i == uf[i] ? i: uf[i] = find(uf[i]);
    }

    int merge(int x, int y){
        x = find(x); y = find(y);
        if(x == y) return cnt[x];
        uf[y] = x;
        //更新合并之后的连通分量的元素个数
        cnt[x] += cnt[y];
        return cnt[x];
    }

    int longestConsecutive(vector<int>& nums) {
        if(nums.size() == 0) return 0;
        for(int i: nums) uf[i] = i, cnt[i] = 1;
        int ans = 1;
        for(int i: nums){
            if(i != INT_MAX && uf.count(i+1)) ans = max(ans, merge(i, i+1));
        }
        return ans;
    }
};

 

posted @ 2020-09-22 20:24  图神经网络  阅读(113)  评论(0编辑  收藏  举报
Live2D