[LeetCode] 128. Longest Consecutive Sequence(最長連續序列)
阿新 • • 發佈:2020-12-20
- Difficulty: Hard
- Related Topics: Array, Union Find
- Link: https://leetcode.com/problems/longest-consecutive-sequence/
Description
Given an unsorted array of integers nums
, return the length of the longest consecutive elements sequence.
給定一個無序整數陣列 nums
,尋找其最長連續序列,返回其長度。
Follow up
Could you implement the O(n)
你能以 \(O(N)\) 時間複雜度解決嗎?
Examples
Example 1
Input: nums = [100,4,200,1,3,2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.
Example 2
Input: nums = [0,3,7,2,5,8,4,6,0,1]
Output: 9
Constraints
0 <= nums.length <= 1e4
-1e9<= nums[i] <= 1e9
Solution
這題的一個比較暴力的解法就是一個個遍歷。對於每個 num
,依次考察 num + 1
, num + 2
等是否在陣列內,並更新結果。這種做法時間複雜度為 \(O(N^3)\),通過將陣列轉換成 set,可以降低至 \(O(N^2)\),程式碼如下:
import kotlin.math.max class Solution { fun longestConsecutive(nums: IntArray): Int { if (nums.size < 2) { return nums.size } val numSet = nums.toSet() var result = 1 for (num in nums) { var curResult = 1 var n = num + 1 while (n in numSet) { n++ curResult++ } result = max(result, curResult) } return result } }
\(O(N)\) 的做法在 discussion 裡找到一個。建立一個 map,key 為 num,value 為 num 所在的連續序列的最大長度。對每個不在 map 裡的 num,先檢查 num + 1 和 num - 1 是否在這個 map 裡,更新 num 所在的連續序列的最大長度並儲存。程式碼如下:
import kotlin.math.max
class Solution {
fun longestConsecutive(nums: IntArray): Int {
var result = 0
val map = hashMapOf<Int, Int>()
for (num in nums) {
if (!map.containsKey(num)) {
val left = map[num - 1]?:0
val right = map[num + 1]?:0
val sum = left + right + 1
map[num] = sum
result = max(result, sum)
map[num - left] = sum
map[num + right] = sum
}
}
return result
}
}