题目
给定一个未排序的整数数组 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
提示:
- 0 <= nums.length <= 105
- 109 <= nums[i] <= 109
题解
Problem: 128. 最长连续序列
思路
-
首先关注题目中给的用例,发生用例中存在重复的数字,重复的数字的结果的输出是没有影响的,重复的数字会影响我们处理数据的时间,故使用hash表去重。
-
怎么找到一串连续的序列?连续的序列的特征是,假设某个数为x,则序列为x+1,x+2,x+3,x+4…,x+y,这个序列一共y + 1个数字,我们可以运用这个特征去找一个数字后面有多少连续的数字,然后再结合set.contains的的特点快速查询某个数字是否存在,一次查找最多查到到n个数字,然后把n个数字作为结果存起来
-
那么我们是不是可以循环第2步,找到每次查询的几个连续数字,查询一次就更新一次结果,更新策略为Math.max(res, 当前查询的个数)
-
优化:这么做好像已经把问题解决了,但是想一想是否有优化的空间,如果有1,2,3,4,5 这么一串序列,当x为1的时候会去找x+1,x+2,x+3…一共5个数字,这没问题,当x为2的时候继续找x+1,x+2,x+3…一共4个数字,我们发现有很多数字重复查找了,可以通过set.contains(x-1)来判断是否向后查找,如果返回true这表示这个数字以及后面的数字都被查找过了
复杂度
- 时间复杂度: O(n)
- 空间复杂度: O(n)
class Solution {
public int longestConsecutive(int[] nums) {
if(nums.length == 0) return 0;
Set<Integer> set = new HashSet<>();
for(int num : nums) {
set.add(num);
}
int res = 1;
for(int num : set) {
if(set.contains(num-1)){
continue;
}
int tmp = 0;
while(set.contains(num++)){
tmp++;
}
res = Math.max(res, tmp);
}
return res;
}
}
func longestConsecutive(nums []int) int {
if len(nums) == 0 {
return 0
}
var set = make(map[int]int)
for _, num := range nums {
set[num] = 0;
}
var res = 1;
for num, _ := range set {
if _, ok := set[num-1]; ok {
continue
}
tmp := 0
flag := true
for flag {
if _, ok := set[num]; ok {
tmp++
num++
} else {
flag = false
}
}
res = int(math.Max(float64(res), float64(tmp)))
}
return res
}
如果觉得写的不错的话,点个赞吧
作者:我在网吧学编程
链接:https://leetcode.cn/problems/longest-consecutive-sequence/solutions/2887583/shi-yong-hashbiao-qu-zhong-ran-hou-yi-ci-j06o/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。