周末也要来刷题 128 ~ 最长的连续 subsequence
基本信息
- 题号:128
- 题厂:谷歌
- 难度系数:中
已知一个数组,问数组里面连续整数有多少个?
例如:nums = [100,4,200,1,3,2] 返回 4, 因为[1, 2, 3, 4] 为连续整数,长度为 4
解题思路
- 算连续整数有多少个,很容易想到先把数组排序,然后遍历一遍前后比较;
- 涉及排序,于是时间复杂度为 O(n logn)
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
# 当数组长度小于或等于 1 时,无需排序。数组多长就有多少连续元素……提前返回
if len(nums) <= 1:
return len(nums)
nums.sort()
curStreak = 1
longest = 0
# 遍历时,如果当前元素和前面的元素连续(相差 1),连续计数器加 1
# 如果当前元素和前面元素不连续(相差 1 以上),说明连续中断。这时重设连续计数器为 1,同时检查要返回的 longest 需不需要更新最大值……
# 如果前后元素相等,那啥也不做,因为还没有进入连续区间
for i in range(1, len(nums)):
if nums[i] != nums[i -1]:
if nums[i] == nums[i - 1] + 1:
curStreak += 1
else:
longest = max(longest, curStreak)
curStreak = 1
return max(longest, curStreak)

最优解??!!
以上先排序再计算连续个数的方法,貌似效率挺高。然而这并不是本题最优解……

题目要求时间复杂度要控制在 O(n)以内,于是还得继续想办法😵……这时 set 这种保证元素不重复的数据结构登场了……
我们通过查看与当前元素连续的整数是否在 set 内,来检测有多少个连续整数……
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
longest = 0
num_set = set(nums)
# 把数组转化为 set 后,遍历数组时,先找到「开头」(前元素与当前元素不连续)
# 然后开始计算后元素是否在 set 内,如果在计数器➕1;如果不在跳出循环,更新最长连续记录……
for n in nums:
if n - 1 not in num_set:
cur_n = n
cur_streak = 1
while (cur_n + 1) in num_set:
cur_n += 1
cur_streak += 1
longest = max(cur_streak, longest)
return longest

Constraints
0 <= nums.length <= 105-109 <= nums[i] <= 109
Big O(最优解)
- Time:O(n)
- Space:O(n)—— set 空间
测试
- 数列为空时
- 数列为 1 时
- 数列元素有重复时
- ……
总结
- 也是中规中矩中档题啊😭