题目
给定一个未排序的整数数组 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
示例 3:输入:nums = 1,0,1,2
输出:3
提示:0 <= nums.length <= 105
-109 <= numsi <= 109
解法1:排序后暴力
- 对于int 数组,利用sort方法进行升序排序,以 下面的代码为例,排序后为1 , 1 , 2 , 2 , 3 , 4 , 100 , 200
- 设定当前数组位置从 i = 0 开始,比较 numsi 和 numsi+1 的关系
- 如果 numsi +1 == numsi+1,当前长度加一;
- 如果 numsi == numsi+1,则进行跳过;
- 如果都不满足,则设定当长度 cur = 0 ,比较当前值cur和最大值longest,更大的作为新的longest;
- 返回最后一个连续子串长度 cur 和 之前最大字串长度的最大值
java
public class Longest_consecutive_sequence {
public static int longestConsecutive(int[] nums) {
if (nums == null || nums.length == 0)
return 0;//为0的考虑,也可想步骤2一样初始设置为0,最后返回为0
Arrays.sort(nums);//先给这个数组进行排序
int longest = 1;//待比较的最大串
int current = 1;//当前最长长度
for (int i = 0; i < nums.length-1; i++) {
if (nums[i] + 1 == nums[i+1]) {
current++;
}
else if (nums[i] == nums[i+1]) {
continue;
}
else{
longest = Math.max(longest, current);
current = 1;
}
}
return Math.max(longest, current);//当前最长和最后的cur进行比较
}
public static void main(String[] args) {
int[] x = new int[]{100, 4, 200, 1, 3, 1, 2, 2};
System.out.println(longestConsecutive(x));
}
}
解法2:Set存储后依次查找
- 遍历每一个数组中的每一个元素,将其存放在HashSet结构中(Set中的元素不重复)
遍历Set中的每一个元素(注意这里是遍历Set不是遍历原数组,原数组中可能存在多个重复值,复杂度变高)- 对于Set中的每一个元素,若没有比当前元素更小一个的值,即 i-1,则证明该元素是子序列中最小值,此时开始依次循环记录连续序列的长度,直到不连续,则在之前最长长度 max 和当前长度 current 中选取最大值即可
java
public class Longest_consecutive_sequence {
public static int longestConsecutive(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int num : nums) set.add(num);
int max = 0;
for (int i: set) {
if(!set.contains(i-1)) {
int temp = i + 1;
int current = 1;
while (set.contains(temp)) {
current++;
temp++;
}
max = Math.max(max, current);
}
}
return max;
}
}