Leetcode 128 Longest Consecutive Sequence
阿新 • • 發佈:2020-10-25
題目介紹
給定未排序的整數序列,判斷裡面最長的連續元素長度。需要在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
出現在此序列中,表明已經被遍歷過可以跳過了。其中in
在set
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-find
和quick-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