最长连续序列-leetcode
题目描述
给定一个未排序的整数数组 nums
,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n)
的算法解决此问题。
解法一
思路:
采用排序的方法,对于一个数组,首先存入集合当中,利用集合对其进行去重,去重之后对其排序,再利用两个for循环进行判断,例如集合[9,1,4,7,3,-1,0,5,8,-1,6]
进行上述操作后变为[-1,0,1,3,4,5,6,7,8,9]
,从-1开始匹配,匹配到1,此时长度为3,之后不从0开始匹配,因为从0开始也只会匹配到1,是个重复操作,此时直接从第一次不匹配项3开始新一轮的匹配。
采用了排序时间复杂度不为O(n),但是可以通过测试。
代码:
import java.util.*;
import java.util.stream.Collectors;
public class leetcode_003 {
public static int longestConsecutive(int[] nums) {
if (nums == null || nums.length == 0) return 0;
// 使用 Arrays.stream() 方法
Set<Integer> hashSet = Arrays.stream(nums)
.boxed()
.collect(Collectors.toCollection(HashSet::new));
int[] num_new=hashSet.stream().mapToInt(Integer::intValue).toArray();
Arrays.sort(num_new);
if (num_new.length == 1) return 1;
int max_len=0,len=1;
//提高这段的代码的速度!!!!
int por=0;
for (int i = 0; i < num_new.length-1; i=por) {
for (int j = i+1; j < num_new.length; j++) {
if (num_new[i]+j-i!=num_new[j]) {
max_len=Math.max(max_len,len);
por=j;
len=1;
break;
}
len++;
if(j==num_new.length-1){
max_len=Math.max(max_len,len);
return max_len;
}
}
}
return max_len;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
List<Integer> list = new ArrayList<>();
String[] line = sc.nextLine().split(",");
int[] nums = Arrays.stream(line).mapToInt(Integer::parseInt).toArray(); //转换为int数组
int max_len = longestConsecutive(nums);
System.out.println(max_len);
}
}
解法二
思路:
将其放入到hashset中,利用集合查询时间复杂度为O(1),关键优化:如果 x−1 在哈希集合中,则不以 x 为起点。因为以 x−1 为起点计算出的序列长度,一定比以 x 为起点计算出的序列长度要长。这样可以避免大量重复计算。
代码:
import java.util.*;
public class leetcode_003 {
public static int longestConsecutive(int[] nums) {
Set<Integer> st = new HashSet<>();
for (int num : nums) {
st.add(num); // 把 nums 转成哈希集合
}
int ans = 0;
for (int x : st) { // 遍历哈希集合
if (st.contains(x - 1)) { // 如果 x 不是序列的起点,直接跳过
continue;
}
// x 是序列的起点
int y = x + 1;
while (st.contains(y)) { // 不断查找下一个数是否在哈希集合中
y++;
}
// 循环结束后,y-1 是最后一个在哈希集合中的数
ans = Math.max(ans, y - x); // 从 x 到 y-1 一共 y-x 个数
}
return ans;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
List<Integer> list = new ArrayList<>();
String[] line = sc.nextLine().split(",");
int[] nums = Arrays.stream(line).mapToInt(Integer::parseInt).toArray(); //转换为int数组
int max_len = longestConsecutive(nums);
System.out.println(max_len);
}
}