题目
给定一个未排序的整数数组 nums
,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n)
的算法解决此问题。
示例 1:
1 2 3 输入:nums = [100,4,200,1,3,2] 输出:4 解释:最长数字连续序列是 [1, 2, 3, 4] 。它的长度为 4 。
示例 2:
1 2 输入:nums = [0,3,7,2 ,5,8,4,6 ,0 ,1 ] 输出:9
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
题解
Python
法一:哈希表
思路
先把 nums
转为哈希集合(set),也就是说,我们要把原先会存在重复数据的列表变成无重复数据的集合,再遍历集合,如果
x - 1 存在集合中,说明 x
不是一个连续序列的起点,就跳过当前数据,继续往后找。如果 x
是序列起点,用 y = x + 1 表示其后续的一个元素,如果 y 在集合里,y
自增,然后继续看 y 是否在集合里,直到退出循环。
结果 ans 就为 ans 和 y - x (表示序列长度)的最大值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution : def longestConsecutive (self, nums: List [int ] ) -> int : ans = 0 st = set (nums) for x in st: if x - 1 in st: continue y = x + 1 while y in st: y += 1 ans = max (ans, y - x) return ans
法二:排序
思路
朴素解法:排序后查找连续序列
解题过程
先对序列进行排序,然后进行一次遍历,遍历时进行以下判断:
如果当前 index 默认为 0,说明是第一个数,默认要 + 1;
如果当前位置的数,比前一个数刚好大 1,当前最长连续序列 temp +
1;
如果当前位置的数和前一个数一样大,那么继续遍历;
如果当前位置的数 > 前一个数 + 1,更新结果 res ,重置 temp 。
最后需要注意,可能整个数组都是连续的,返回的结果再使用 max()
返回最大的序列长度。
复杂度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution : def longestConsecutive (self, nums: List [int ] ) -> int : if len (nums) == 0 : return 0 sorted_nums = sorted (nums) res = -float ('inf' ) temp = 0 for index, num in enumerate (sorted_nums): if index == 0 or sorted_nums[index] == sorted_nums[index - 1 ] + 1 : temp += 1 elif sorted_nums[index] == sorted_nums[index - 1 ]: continue else : if res < temp: res = temp temp = 1 return max (res, temp)
运行结果
Java
我的本题解法应该是纯基于数组来做的,时间复杂度击败98.52%,空间复杂度击败90.44%,算是比较不错的解法了。
最基本的思想就是先排序,然后我们再找最长的连续序列。
算法步骤:
排序
初始化结果res
和每轮的最大长度tempMax
从下标0
到倒数第二个数开始,遍历nums
数组:
注意最后一个数字没有进行比较,这里需要将最后一个数字如果连续或者相等(防止后面好几个数字一直都是连续的情况),tempMax++
,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public int longestConsecutive (int [] nums) { if (nums.length == 0 ) { return 0 ; } else if (nums.length == 1 ) { return 1 ; } Arrays.sort(nums); int res = Integer.MIN_VALUE, tempMax = 0 ; for (int i = 0 ; i < nums.length - 1 ; i++) { if (nums[i + 1 ] == nums[i]) { continue ; } else if (nums[i + 1 ] == nums[i] + 1 ) { tempMax++; } else { res = Math.max(tempMax + 1 , res); tempMax = 0 ; } } if (nums[nums.length - 1 ] == nums[nums.length - 1 - 1 ] + 1 || nums[nums.length - 1 ] == nums[nums.length - 1 - 1 ]) { tempMax++; } res = Math.max(tempMax, res); return res; } }