【LeetCode】128. Longest Consecutive Sequence

128. 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

题意:给定一个无序数组,数组中可能存在重复元素,数组中最长的连续序列长度。

解答

方法一:

这个方法采用了map来帮助完成功能。在遍历过程中,map键值是元素的值,如果此时这个元素是一个序列中的边界,如有序列,1到3,map键值对应的值就是这个序列的长度,即map[1] = 3,且map[3] = 3。

class Solution {
public:
    int longestConsecutive(vector<int>& nums) 
    {
        unordered_map<int,int> help;
        int res = 0;
        for(auto val:nums)
        {
            if(help[val])   continue;

            int left = help[val-1];
            int right = help[val+1];
            res = max(res,help[val-left] = help[val+right] = help[val] = left+right+1);
        }
        return res;
    }
};

方法二

并查集。这个方法时间复杂度和空间复杂度都很高,并不推荐,写在这里只是为了让自己学习并查集这个算法。

class Union_Set
{
public:
    Union_Set(int n):mark(n)
    {
        for(int i = 0; i < n; ++i)  mark[i] = i;
    }

    void make_union(int a,int b)
    {
        int aroot = find(a);
        int broot = find(b);
        mark[aroot] = broot;
    }

    int find (int a)
    {
        while(a != mark[a])
            a = mark[a];
        return a;
    }
    int max_union()
    {
        vector<int> temp(mark.size());
        int res = 0;
        for(int i = 0; i < mark.size(); ++i)
        {
            res = max( res,++temp[find(i)] );
        }
        for(auto val:mark)
            cout << val << " ";
        cout << endl;
        return res;
    }
private:
    vector<int> mark;
};
class Solution {
public:
    int longestConsecutive(vector<int>& nums) 
    {
        //并查集方法
        unordered_map<int,int> help;
        Union_Set record(nums.size());
        for(int i = 0; i < nums.size(); ++i)
        {
            if(help.find(nums[i]) != help.end())    continue;
            help[nums[i]] = i;
            if(help.find(nums[i]-1) != help.end())  record.make_union(help[nums[i]-1],i);
            if(help.find(nums[i]+1) != help.end())  record.make_union(help[nums[i]+1],i);
        }
        return record.max_union();
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值