边练习边更新,加油!!!
题目:
给定一个未排序的整数数组 nums
,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n)
的算法解决此问题。
示例 1:
输入:nums = [100,4,200,1,3,2] 输出:4 解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
注意点:
- 重复的数没有意义,可以用集合去重
- 用排序是nlogn,超过复杂度(集合没有顺序,用sorted会转化为列表)【list.sort(
key=None, reverse=False
)列表内置方法,sorted(list/set/tuple)内置函数】 - 从最小的开始搜索,跳过其他的减少时间
题解做法:
判断连续数组的最小值:x-1不在数组内(同时能保证遇到序列内部的数直接跳过)
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
longest_streak = 0
num_set = set(nums)
for num in num_set:
if num - 1 not in num_set:
current_num = num
current_streak = 1
while current_num + 1 in num_set:
current_num += 1
current_streak += 1
longest_streak = max(longest_streak, current_streak)
return longest_streak
作者:力扣官方题解
链接:https://leetcode.cn/problems/longest-consecutive-sequence/solutions/276931/zui-chang-lian-xu-xu-lie-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
自己的做法:【看题解后通过】
看了题解后[ 用时: 17 m 21 s ]必须一模一样,数量得化简!(集合的查找速度为O(1))【没有用集合的时候超时】
class Solution(object):
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# 排序之后计算
# l = []
#
# for x in nums:
# if x not in l:
# l.append(x)
l = set(nums)
max_num = 0
for x in l:
if x-1 not in l:
n = 1
while x+1 in l:
n += 1
x += 1
if max_num < n:
max_num = n
return max_num
1.错:妄图用字典写明列表左右两边的数值,但不能一遍一遍的反复搜索有没有需要连起来的
序列最小为-x,最大为+x,有正有负就连起来,两个一样也连起来,但和数据出现的次序有关,数据多了没法连
如果去重和排序之后也许能成?但现在还是O(n)的复杂度,加排序又多一堆
class Solution(object):
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# 边上是什么
table = {}
for x in nums:
x0 = x-1
x1 = x+1
x_up = str(x)+"+"
x_down = str(x)+"-"
x0_ = str(x0)+"+"
x1_ = str(x1)+"-"
if x0_ in table and x1_ in table:
table[x0_] = table[x0_] + [x] + table[x1_]
a = str(table[x0_][0])+"-"
b = str(table[x0_][-1])+"+"
table[a] = table.pop(x0_)
table[b] = table[a]
else:
if x0_ in table:
table[x0_] = table[x0_] + [x]
table[x_up] = table.pop(x0_)
if x1_ in table:
table[x1_] = [x] + table[x1_]
table[x_down] = table.pop(x1_)
if x_down not in table:
table[x_down] = [x]
if x_up not in table:
table[x_up] = [x]
for x in nums:
x_up = str(x)+"+"
x_down = str(x)+"-"
if x_down in table and x_up in table:
table[x_down] = table[x_up] + table[x_down][1:]
a = str(table[x_down][0])
b = str(table[x_down][-1])
table[a+"-"] = table.pop(x_down)
table[b+"+"] = table[a+"-"]
if a+"+" in table:
table[str(table[a+"+"][0])+"-"] = table[a+"+"] + table[a+"-"][1:]
if b+"-" in table:
table[str(table[b+"-"][0])+"+"] = table[b+"+"] + table[b+"-"][1:]
max_length = 0
# 遍历字典
for key, value in table.items():
if len(value) > max_length:
max_length = len(value)
print(table)
return max_length
2.时间复杂度高O(n2) :暴力筛选了一下
根本不需要排序,直接找x+1是否在里面就行
当时还不知道有set,自己遍历了去重
class Solution(object):
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# 简单做法
l = []
max_num = 0
for x in nums:
if x not in l:
l.append(x)
l = sorted(l)
for i,x in enumerate(l):
for j,y in enumerate(l[i:]):
if j == y-x:
if max_num < j+1:
max_num = j+1
return max_num
3.时间复杂度高O(nlogn) :暴力筛选了一下
排序之后找到序列最长的就行:相当于双指针,a指针指着序列最小值,b指针遍历,当序列断开后,a指针跑到b指针处
(吐槽:这个时候我都会用双指针了,后面写双指针代码的时候怎么不知道用???)
class Solution(object):
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# 简单做法
l = []
max_num = 0
for x in nums:
if x not in l:
l.append(x)
l = sorted(l)
print(l)
i = 0
n = 1
while i<len(l)-1:
x = l[i]
i += 1
if l[i]==x+1:
n += 1
else:
if max_num < n:
max_num=n
n=1
if max_num < n and len(l) > 0:
max_num=n
return max_num