最長連續子序列 Longest Consecutive Sequence
阿新 • • 發佈:2018-11-25
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; }