1. 程式人生 > >LeetCode-128.最長連續序列(相關話題:並查集)

LeetCode-128.最長連續序列(相關話題:並查集)

給定一個未排序的整數陣列,找出最長連續序列的長度。

要求演算法的時間複雜度為 O(n)。

示例:

輸入: [100, 4, 200, 1, 3, 2]
輸出: 4
解釋: 最長連續序列是 [1, 2, 3, 4]。它的長度為 4。  

並查集:初始時,讓每個元素都作為一個含有單元素的集合存在

然後按照一定順序處理每個元素,將同一組的元素(此題中即為相鄰數字)所在的集合合併

此題中,用Map<Integer, List<Integer>>

key表示每個元素,value為長度為2的陣列,第一個元素為每個元素(key)所屬的集合標識,第二個元素為同一個集合中的元素個數

遍歷所給元素,將相鄰元素所在集合合併,同時更新所屬集合標識和所屬集合中的元素個數

有關並查集的詳解可參考部落格:https://blog.csdn.net/u013546077/article/details/64509038

Java程式碼:

public int longestConsecutive(int[] nums) {
    int len = nums.length, maxCnt = 0;
    Map<Integer, List<Integer>> map = new HashMap<>(len);
    for(int i = 0; i < len; i++){
        if (map.containsKey(nums[i]))
            continue;

        List<Integer> col = new ArrayList<>(2);
        col.add(nums[i]);
        col.add(1);
        if (map.containsKey(nums[i]+1)) {
            col.set(1, map.get(nums[i]+1).get(1)+1);
            map.get(nums[i]+1).set(0, nums[i]);
        }
        if (map.containsKey(nums[i]-1)) {
            col.set(0, nums[i]-1);
            int key = nums[i]-1;
            while (key != map.get(key).get(0)){
                map.get(key).set(1, map.get(key).get(1) + col.get(1));
                key = map.get(key).get(0);
            }
            map.get(key).set(1, map.get(key).get(1) + col.get(1));
            maxCnt = Math.max(maxCnt, map.get(key).get(1));
        }
        maxCnt = Math.max(maxCnt, col.get(1));
        map.put(nums[i], col);
    }

    return maxCnt;
}