Leetcode上的一道习题:
Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
Your algorithm should run in O(n) complexity.
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.
给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
示例:
输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
看似简单,标注为困难,关键是时间复杂度的限制,显而易见的O(nlogn)时间复杂度算法:对数组进行全排序,然后再扫描一遍排序数组,不过不用试也知道肯定这道题过不了
利用并查集思想和字典解决,尤其是Python的简洁表述,代码如下:
class Solution:
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if nums==None or len(nums)==0:
return 0
rmap,vmap={},{} #这里可以使用单一字典形成 key->(rank,value) 映射,然而如此代码比较乱,读者可以一试
for e in nums:
if e not in rmap:
rmap[e],vmap[e]=e,1 #新元素初始指向自己,连续序列值value为1
if e+1 in rmap: #若当前元素紧邻右边有元素,当前元素value+=右边元素value
vmap[e]+=vmap[e+1]
if e-1 in rmap: #若当前元素紧邻左边有元素,更新左边元素的序列头,当前元素指向序列头
vmap[rmap[e-1]]+=vmap[e]
rmap[e]=rmap[e-1]
rmap[rmap[e]+vmap[rmap[e]]-1]=rmap[e] #最后更新当前序列尾的rank,使其指向序列头
tmp,res=max(vmap.items(),key=lambda x: x[1])
return res
仅仅14行代码,结构清晰,python写算法题确实清爽的很
这里稍作分析,题目需要在非排序状态下完成连续序列的计算,基本就是在线算法(一般理解是O(n)时间复杂度,来一个处理一个,就像在线更新一般),使用恰当的数据结构保存重要信息,并在处理新元素时更新。这里需要用字典或并查集数据结构保存已经得到的重要信息,最根本的信息就是所有已知连续序列的头,尾,和序列长度,那么注意在新处理一个元素时,需要更新这三个重要信息,最后,遍历所有连续序列的长度,即可得到正确结果,具体实现细节见代码