特别鸣谢:来自夸夸群的 醉笑陪公看落花@知乎,王不懂不懂@知乎,
感谢醉笑陪公看落花@知乎 倾囊相授,感谢小伙伴们督促学习,一起进步
相关文章
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 1:
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
示例 2:
输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-consecutive-sequence
分析
连续数字序列:每个元素间隔1
限制时间复杂度: O(n)
有相同元素需要先去重
方法1 - 字典+ 并查集 - 超时
将元素存为字典中的键,元素的下标存为值
申请一个dad数组,初始每个元素的父亲是自己
如果两个元素相差1,将dad相应位置设置为较大数字的dad
最后计算dad数组中相同元素的个数
'''
o(n^2) 超时
'''
def solve1(nums):
if len(nums)==0:return 0
mark={}
for idx,e in enumerate(nums):
mark[e]=idx
dad = list(mark.keys())
nums = dad[:]
mark={}
for idx,e in enumerate(nums):
mark[e]=idx
flag = True
while flag:
flag = False
for i in range(len(dad)):
if nums[i]+1 in mark and dad[i]!= dad[mark[nums[i]+1]]:
flag = True
dad[i] = dad[mark[nums[i]+1]] # 并查集合并
return maxCount(dad)
def maxCount(dad):
dic = {}
for elem in dad:
if elem not in dic:dic[elem] = 0
dic[elem]+=1
temp = float('-inf')
for value in dic.values():
temp = max(value,temp)
return temp
方法2 字典+ 链表 - 通过
遍历一次数组,即可建立起连续节点之间的指针
如果某个节点前面没有结点,则是连续数组起点
如果某个节点后面没有节点,则是连续数组的终点
找到起终点,即可计算最大长度了
def solve2(nums):
nums = set(nums)
dic = {}
for i in nums:
dic[i] = node(i,None,None)
for i in nums:
if i+1 in dic:
dic[i].next = dic[i+1]
dic[i + 1].pre = dic[i]
ans = 0
for i in dic:
temp = 1
if dic[i].pre == None:
while(dic[i].next):
i+=1
temp+=1
ans = max(ans,temp)
return ans
class node:
def __init__(self,value,pre,next):
self.value = value
self.pre = pre
self.next = next
在实现过程中发现,不用链表,在hash set中直接可以找到 i+ 1和i-1,得出了下面的方法
方法3 哈希 O(n) 通过
set 中查找i+1 累加长度,set中查找i-1 找起始位置
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
def solve3(nums):
nums = set(nums)
ans = 0
for i in nums:
temp = 1
if i-1 not in nums:
while(i+1 in nums):
i+=1
temp+=1
ans = max(ans,temp)
return ans
return solve3(nums)