leetcode128.最长连续序列

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

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

示例:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-consecutive-sequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

完整代码

看到这道题时想到:先将序列排序,在求最长连续序列的长度,当时时间复杂度是O(nlogn)
下面是哈希思想
参考:官方题解

  • 首先将数组中的数放在set中,排除重复的元素
  • 遍历序列,如果该数a是子序列中的第一个数(也就是说a-1不在序列中),求以该数开始的最长序列
class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        if(nums.size() == 0)
            return 0;
        set<int> m;
        int max = 0;
        for(int i = 0; i < nums.size(); ++i){
            m.insert(nums[i]);
        }
        for(int i = 0; i < nums.size(); ++i){
            if(m.find(nums[i] - 1) == m.end()){//nums[i]是该连续序列的第一个数
                int cur = nums[i];
                while(m.find(cur + 1) != m.end()){
                    ++cur;
                }
                int cur_l = cur - nums[i] + 1;
                if(cur_l > max)
                    max = cur_l;
            }
        }
        return max;
    }
};

参考:动态规划

定义哈希数组,来存储当前数的最长连续序列,遍历每一个数进行求解,如果当前值大于最大值,那更新最大值

  • 当前数a的对应的最长连续序列长度len为:其左面left(a-1)和右面right(a+1)对应的最长连续序列的和再+1
  • 求出len后,需要更新最大长度和两边界点的长度(注:只更新边界就可以,中间的数无所谓,因为中间的数已经出现过了。可以借助[3,2,1,5,4]这个序列来理解,这也体现了动态规划的思想,map数组中存放的只是局部解)
class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        if(nums.size() == 0)
            return 0;
        map<int, int> m;
        int left, right, cur, max = 0;
        for(int i = 0; i < nums.size(); ++i){
            if(m[nums[i]] == 0){
                left = m[nums[i] - 1];
                right = m[nums[i] + 1];
                cur = left + right + 1;
                m[nums[i]] = cur;
                max = (cur > max)? cur : max; 
                m[nums[i] - left] = cur;
                m[nums[i] + right] = cur;
            }
            
        }
        return max;
    }
};

二刷
借助map实现

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        if(nums.size() == 0 || nums.size() == 1)
            return nums.size();
        map<int, int> m;
        for(auto n : nums)
            m[n] = 1;
        auto iter = m.begin(), piter = m.begin();
        int res = 1, cur = 1;
        ++iter;
        while(iter != m.end()){
            cout << iter->first << endl;
            if(iter->first == (piter->first + 1))
                ++cur;
            else
                cur = 1;
            res = max(res, cur);
            ++piter;
            ++iter;
        }
        return res;
    }
};

你可能感兴趣的:(#,算法)