【LeetCode】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.

题解:

Solution 1 

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {int longest_len = 0;
        unordered_map<int, bool> map;
        for(auto n : nums)
            map[n] = false;
        for(auto i : nums){
            if(map[i])
                continue;
            int len = 1;
            for(int j = i + 1; map.find(j) != map.end(); ++j){
                map[j] = true;
                ++len;
            }
            for(int j = i - 1; map.find(j) != map.end(); --j){
                map[j] = true;
                ++len;
            }
            longest_len = max(longest_len, len);
        }
        return longest_len;
    }
};

Solution 2 

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        int longest_len = 0;
        unordered_set<int> set(nums.begin(), nums.end());
        for(auto i : nums){
            if(set.find(i) == set.end())
                continue;
            set.erase(i);
            int prev = i - 1, next = i + 1;
            while(set.find(prev) != set.end()) set.erase(prev--);
            while(set.find(next) != set.end()) set.erase(next++);
            longest_len = max(longest_len, next - prev - 1);
        }
        return longest_len;
    }
};

Solution 3 

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        int longest_len = 0;
        unordered_map<int, int> map;
        for(auto n : nums){
            if(map.find(n) != map.end())
                continue;
            int prevsum = map.find(n - 1) != map.end() ? map[n - 1] : 0;
            int nextsum = map.find(n + 1) != map.end() ? map[n + 1] : 0;
            int sum = prevsum + nextsum + 1;
            map[n] = sum;
            map[n - prevsum] = sum;
            map[n + nextsum] = sum;
            longest_len = max(sum, longest_len);
        }
        return longest_len;
    }
};

 union find操作,连续序列可以用两段和长度来表示,这里只需要两端就可以求出长度。

Solution 3 

// Author: @advancedxy
class Solution {
public:
    int longestConsecutive(vector<int> &nums) {
        unordered_map<int, int> map;
        int size = nums.size();
        int len = 1;
        for (int i = 0; i < size; i++) {
            if (map.find(nums[i]) != map.end()) continue;
                map[nums[i]] = 1;
            if (map.find(nums[i] - 1) != map.end()) {
                len = max(len, mergeCluster(map, nums[i] - 1, nums[i]));
            }
            if (map.find(nums[i] + 1) != map.end()) {
                len = max(len, mergeCluster(map, nums[i], nums[i] + 1));
            }
        }
        return size == 0 ? 0 : len;
        }
private:
    int mergeCluster(unordered_map<int, int> &map, int left, int right) {
        int upper = right + map[right] - 1;
        int lower = left - map[left] + 1;
        int length = upper - lower + 1;
        map[upper] = length;
        map[lower] = length;
        return length;
    }
};

(from 九章算法)

原文地址:https://www.cnblogs.com/Atanisi/p/7466211.html