zoukankan      html  css  js  c++  java
  • 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;
        }
    }
  • 相关阅读:
    数据结构和算法关系
    x轴滚动
    常用Python第三方库简介
    devgridContral
    第一次线程使用经验总结
    调取图片出现的的内存泄露,导致大红叉
    IEEE754 处理数据变换
    c# 基础任务1
    Python-常用第三方库
    C#高性能大容量SOCKET并发(八):通讯协议
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7985468.html
Copyright © 2011-2022 走看看