1. 程式人生 > >最長連續子序列 Longest Consecutive Sequence

最長連續子序列 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;
    }