leetcode128求最长连续序列

leetcode 128 Longest Consecutive Sequence

Posted by BY on June 7, 2020

前言

又是好久没有更新了

正文

问题来源

本问题来自leetcode上的128题。

问题描述

给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。

示例 1:

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

分析:

题目提示是并查集,于是就按并查集的想法来做:
首先每个数字是个单独一个集合,如果两个数相差为一则认为是同一个集合。
每个数字初始化情况leader指向自身,并且这个集合类的总数为1;若一个数与存在另外一个数绝对值相差只为1,则这个数需要融入另外一个数的集合内;若一个数与存在相差为1并且为-1的数,这个数和这两个数所在的集合要合并在一起;如何判断是在同一个集合,该数字leader(或者递归)指向同一个数。

type Node struct {
    Leader int
    Count int
}

func findLeader(m map[int]*Node, f int) (int,bool) {
    Lnode, ok := m[f]
    if !ok {
        return 0, false
    }
    if f == Lnode.Leader {
        return f, true
    }
    return findLeader(m, m[f].Leader)
}

func longestConsecutive(nums []int) int {
    m := make(map[int]*Node) 
    max := 0
    for _, i := range nums {
        if _, ok := m[i]; ok {
            continue
        }
        v1, ok1 := findLeader(m, i-1)
        v2, ok2 := findLeader(m, i+1)
        if ok1 {
            if ok2 {
                m[v1].Count += m[v2].Count + 1 
                m[v2].Leader = v1
                m[i] = &Node{Leader:v1, Count:0}
                if max < m[v1].Count {
                    max = m[v1].Count
                }
            } else {
                m[v1].Count += 1 
                m[i] = &Node{Leader:v1, Count:0}
                if max < m[v1].Count {
                    max = m[v1].Count
                }
            }
        } else {
            if ok2 {
                m[v2].Count += 1
                if max < m[v2].Count {
                    max = m[v2].Count
                }
                m[i] = &Node{Leader:v2, Count:0}
            } else {
                m[i] = &Node{Leader:i, Count:1}
                if max < 1 {
                    max = 1
                }
            }
        }
        
    }
    //fmt.Println(m)
    return max
}

其他人的解法一

public class Solution {
    public int longestConsecutive(int[] nums) {
        int res = 0;
        Set<Integer> s = new HashSet<Integer>();
        for (int num : nums) s.add(num);
        for (int num : nums) {
            if (s.remove(num)) {
                int pre = num - 1, next = num + 1;
                while (s.remove(pre)) --pre;
                while (s.remove(next)) ++next;
                res = Math.max(res, next - pre - 1);
            }
        }
        return res;
    }
}

其他人的解法二

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        int res = 0;
        unordered_map<int, int> m;
        for (int num : nums) {
            if (m.count(num)) continue;
            int left = m.count(num - 1) ? m[num - 1] : 0;
            int right = m.count(num + 1) ? m[num + 1] : 0;
            int sum = left + right + 1;
            m[num] = sum;
            res = max(res, sum);
            m[num - left] = sum;
            m[num + right] = sum;
        }
        return res;
    }
};

总结:

勤思考。

结语

不管怎么样好好加油。