1. 程式人生 > 實用技巧 >Leetcode 128 Longest Consecutive Sequence

Leetcode 128 Longest Consecutive Sequence

題目介紹

給定未排序的整數序列,判斷裡面最長的連續元素長度。需要在O(n)複雜度內完成。

Example:

Input: [100, 4, 200, 1, 3, 2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.

Solutions

簡單解法

因為在O(n)複雜度內,所以不能進行排序。在討論區看到一個很簡單的解法:

對每個元素,判斷其+1+2是否也在序列中,如果元素-1出現在此序列中,表明已經被遍歷過可以跳過了。其中inset

中的時間複雜度為O(1)

class Solution(object):
    def longestConsecutive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        nums = set(nums)
        res = 0
        for num in nums:
            if num - 1 in nums:
                continue
            best = 1
            while num + 1 in nums:
                best += 1
                num += 1
            res = max(best, res)
        return res

Union-Find

union-find可以分為兩種,quick-findquick-union。顧名思義,前者是查詢比較快,後者是聯結比較快。原因在於,quick-find的聯結過程是需要遍歷所有的節點,將原本指向某一節點的節點指向需要聯結的節點。而quick-union是需要遍歷一個節點直到其根節點,然後再將根節點與聯結的節點的根節點進行聯結。

這題採用quick-union的思路。連線的是下標,不是nums中的值。

class Solution(object):
    def longestConsecutive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        self.idx = [0 for i in range(len(nums))]
        d = {}
        self.start(nums)
        for i in range(len(nums)):
            if nums[i] in d:
                continue
            else:
                d[nums[i]] = i
            if nums[i] + 1 in d:
                self.union(i, d[nums[i] + 1])
            if nums[i] - 1 in d:
                self.union(d[nums[i] - 1], i)
        return self.count()

    def start(self, nums):
        for i in range(len(nums)):
            self.idx[i] = i

    def find(self, p):
        # 尋找最終的根節點
        while p != self.idx[p]:
            p = self.idx[p]
        return p

    def union(self, p, q):
        proot = self.find(p)
        qroot = self.find(q)
        # 將p的根節點改為q的根節點
        self.idx[proot] = qroot

    def count(self):
        res_count = {}
        res = 0
        for i in range(len(self.idx)):
          	# 關鍵要統計每一個節點的根節點
            root = self.find(self.idx[i])
            if root not in res_count:
                res_count[root] = 1
            else:
                res_count[root] += 1
            res = max(res_count[root], res)
        return res