leetcode128- Longest Consecutive Sequence- hard

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.

O(n)。突破关键是去找上下是否有出现过。sequence就是可以随便取,这题还不要求顺序,那就是真真随便取。完全set概念了有出现即可。

法1:HashSet(更优更好写)。
1.先把所有元素都放到set里。 
2.遍历number,取出一个元素,用up和down分别count和它连续的数的个数,每次找到+1-1的数计数好后就把它们在set中remove掉。然后把这个up和down夹出来的个数打个擂台。
细节:
1.一开始遍历统计的set和后来用来避免重复查同一元素的visited set可以直接共用一个。只要visit以后把set里的这个元素删掉即可。
2.不用同时维护length+up指针+down指针,最后可以直接用up, down指针的位置得到length的。
 
法2.UnionFind + HashMap<value, index>。
用fathers[]当基础数据结构,count[]记录每个集合内的个数, map帮忙记录某个值在哪个index方便后续的union。 遍历number,如果发现上下元素有出现过,那就把它们合到一起。要记得在union的时候,把count合并一下,合并count后打擂台。 

我的实现1:

class Solution {
        public int longestConsecutive(int[] nums) {
            Set<Integer> set = new HashSet<>();
            for (int i : nums) {
                set.add(i);
            }

            Set<Integer> visited = new HashSet<>();
            int ans = 0;
            for (int i : set) {
                if (visited.contains(i)) {
                    continue;
                }
                int len = 1;
                int offset = 1;
                while (set.contains(i + offset)) {
                    visited.add(i + offset);
                    len++;
                    offset++;
                }
                offset = -1;
                while (set.contains(i + offset)) {
                    visited.add(i + offset);
                    len++;
                    offset--;
                }
                ans = Math.max(ans, len);
            }
            return ans;
        }
    }

实现1 九章优雅版

public class Solution {
    /**
     * @param nums: A list of integers
     * @return an integer
     */
    public int longestConsecutive(int[] num) {
        // write you code here
        Set<Integer> set = new HashSet<>();
        for (int item : num) {
            set.add(item);
        }

        int ans = 0;
        for (int item : num) {
            if (set.contains(item)) {
                set.remove(item);

                int l = item - 1;
                int r = item + 1;
                while (set.contains(l)) {
                    set.remove(l);
                    l--;
                }
                while (set.contains(r)) {
                    set.remove(r);
                    r++;
                }
                ans = Math.max(ans, r - l - 1);
            }
        }
        return ans;
    }
}

实现2:

class Solution {

    private int maxL = 1;
    public int longestConsecutive(int[] nums) {
        if (nums == null || nums.length == 0 ) {
            return 0;
        }
        int[] fathers = new int[nums.length];
        int[] count = new int[nums.length];
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            fathers[i] = i;
            count[i] = 1;
        }
        for (int i = 0; i < nums.length; i++) {
            if (map.containsKey(nums[i])) {
                continue;
            }
            if (map.containsKey(nums[i] - 1)) {
                union(fathers, count, i, map.get(nums[i] - 1));
            }
            if (map.containsKey(nums[i] + 1)) {
                union(fathers, count, i, map.get(nums[i] + 1));
            }
            map.put(nums[i], i);
        }
        return maxL;
    }

    private int find(int[] fathers, int x) {
        if (fathers[x] == x) {
            return x;
        }
        return fathers[x] = find(fathers, fathers[x]);
    }

    private boolean union(int[] fathers, int[] count, int x, int y) {
        int fatherX = find(fathers, x);
        int fatherY = find(fathers, y);
        if (fatherX != fatherY) {
            fathers[fatherY] = fatherX;
            count[fatherX] += count[fatherY];
            maxL = Math.max(maxL, count[fatherX]); 
        }
        return fatherX != fatherY;
    }
}
原文地址:https://www.cnblogs.com/jasminemzy/p/7985468.html