最长连续子序列 Longest Consecutive Sequence

2018-11-25 16:28:09

问题描述:

问题求解:

方法一、如果不要求是线性时间的话,其实可以很直观的先排序在遍历一遍就可以得到答案,但是这里明确要求是O(n)的时间复杂度,那么就给了一个强烈的提示就是使用Hash来进行解决。方法一的思路很明确也很暴力,就是将所有的数字都保存到一个Hash表中,如果当前的数字是首个元素,那么就从他开始往后串连,得到以当前数字为首的最长连续序列,最后取max即可。时间复杂度是O(n),因为至多只会读取一个元素两次。

    public int longestConsecutive(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        int res = 0;
        Set<Integer> set = new HashSet<>();
        for (int i : nums) set.add(i);
        for (int i : nums) {
            if (set.contains(i - 1)) continue;
            int len = 1;
            while (set.contains(i + 1)) {
                len++;
                i++;
            }
            res = Math.max(res, len);
        }
        return res;
    }

方法二、这个解法就难思考到一点,当然了依然是使用hash,只是这次保存的以当前为末尾的最长的序列的长度,之后如果重复读取则直接过滤掉,如果不是重复元素,那么就需要对其进行判断,如果左右有元素那么就会生成新的长度的序列,最后只需要遍历一遍hash即可。

    public int longestConsecutive(int[] nums) {
        if (nums.length == 0 || nums.length == 1) return nums.length;
        int res = 0;
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int num : nums) {
            if (map.containsKey(num)) continue;
            int l = map.getOrDefault(num - 1, 0);
            int r = map.getOrDefault(num + 1, 0);
            int len = l + r + 1;
            if (l != 0 && r != 0) {
                map.put(num - l, len);
                map.put(num + r, len);
            }
            else if (l != 0) {
                map.put(num - l, len);
            }
            else if (r != 0) {
                map.put(num + r, len);
            }
            map.put(num, len);
        }
        for (int key : map.keySet()) res = Math.max(res, map.get(key));
        return res;
    }

猜你喜欢

转载自www.cnblogs.com/TIMHY/p/10016058.html