一、题目描述
给定一个未排序的整数数组 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
二、代码思路
首先,题目说没有排序的数组而且是从未排序数组中找最长连续的子序列,也就是数组中可能不挨着,但是有大小关系的子序列。
其次,我们考虑解法,显然有一种暴力解法:
- 逐个把数组中的每个元素都当成序列的第一个元素 x,然后遍历数组依次往后找是否存在x + 1。
- 这种解法是通过遍历找x + 1,显然需要o(n)
第二种解法:
- 逐个把数组中的每个元素都当成序列的第一个元素 x,然后从数组中找是否存在x + 1。
- 我们可以利用HashMap 与 HashSet 查找效率高的特点来找元素。显然找元素时间复杂度未o(1)
- 但是这种解法依旧很慢,因为 1 2 3 4,我们从1开始找四次,如果我们再次从2开始 3 和 4会被重复找,这就是解法慢的原因。
第三种解法:
- 第三种解法的思想很重要:假如序列是 100 99 1 2 3,那么我们开始找的时候应该找的是序列的最开始的头,也就是100 和 1,这样就不会出现重复找的情况。
- 具体判断条件就是,hashmap中是否存在 x - 1这个前序元素,不存在就是序列的第一个。
三、代码题解
package leetcode.lc20230103;
import java.util.HashMap;
/*
* @author lzy
* @version 1.0
* */
public class Solution01 {
public int longestConsecutive(int[] nums) {
if (nums.length == 0) {
return 0;
}
HashMap<Integer, Integer> map = new HashMap();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], 1);
}
int res = 1;
for (int i = 0; i < nums.length; i++) {
if (map.containsKey(nums[i] - 1)) {
continue;
}
int key = nums[i] + 1;
int count = 1;
while (map.containsKey(key)) {
count++;
key++;
}
res = res > count ? res : count;
}
return res;
}
}