[LeetCode] 128. Longest Consecutive Sequence(最长连续序列)
- 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)
solution?
你能以 \(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
}
}