题目
题目描述:
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 输入:nums = [100,4,200,1,3,2] 输出:4 解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。 输入:nums = [0,3,7,2,5,8,4,6,0,1] 输出:9 0 <= nums.length <= 104 -109 <= nums[i] <= 109
实现
主函数:为了测试UT
public static void main(String[] args) {
int[] nums = new int[]{1, 2, 0, 1};
int result = longestConsecutive(nums);
System.out.println(result);
}
暴力做法:时间复杂度O(n logn)
/**
* 暴力做法
* 耗时32ms,内存消耗57MB
*
* @param nums 集合
* @return 最长序列
*/
private static int longestConsecutive(int[] nums) {
if (nums.length <= 1) {
return nums.length;
}
// DualPivotQuicksort双轴快排,数据量小插入排序,数据量大归并排序,时间复杂度O(n log(n))
Arrays.sort(nums);
// 去重时间复杂度O(n)
int[] nums_distinct = Arrays.stream(nums).distinct().toArray();
int longestLen = 0;
int start = 0;
int end;
// 遍历一遍时间复杂度O(n)
for (end = 1; end < nums_distinct.length; end++) {
if (nums_distinct[end] != nums_distinct[end - 1] + 1) {
start = end;
}
longestLen = Math.max((end - start + 1), longestLen);
}
longestLen = Math.max((end - start), longestLen);
return longestLen;
}
哈希表遍历:时间复杂度O(n)
/**
* 哈希表遍历
* 耗时17ms,内存消耗56.3MB
*
* @param nums 集合
* @return 最长序列
*/
private static int longestConsecutive(int[] nums) {
if (nums.length <= 1) {
return nums.length;
}
// 直接转成HashSet,add、delete、remove、contains时间复杂度O(1)
Set<Integer> set = Arrays.stream(nums).boxed().collect(Collectors.toSet());
int longestLen = 0;
for (Integer element : set) {
// 即从[element, x]开始遍历到x
if (!set.contains(element - 1)) {
int currentElement = element;
int currentLen = 1;
while (set.contains(currentElement + 1)) {
currentElement += 1;
currentLen += 1;
}
longestLen = Math.max(longestLen, currentLen);
}
}
return longestLen;
}
哈希表+并查集:时间复杂度O(n logn)
/**
* 图论——并查集(Union-find Set)是一种精巧的数据结构,主要用于处理一些不相交集合的合并问题
* 一些常见的用途有求连通子图、求最小生成树的Kruskal算法和求最近公共祖先(LCA)等
* 主要操作:
* 1、初始化 init
* 2、查找 find
* 3、合并 union
*/
static class UnionFind {
private Map<Integer, Integer> parents;
// 有参构造函数初始化哈希表,相当于用fa[]来存储每个元素的父节点。
UnionFind(int[] nums) {
this.parents = new HashMap<>();
// 初始化时父节点设置为自己
Arrays.stream(nums).boxed().forEach(element -> parents.put(element, element));
}
// 通过哈希表查询时间复杂度O(1)
int find(int x) {
// 递归出口,当到达了祖先位置,就返回祖先
if (parents.get(x) == x) {
return x;
}
// find(parents.get(x))不断往上查找祖先,也进行了路径压缩
parents.put(x, find(parents.get(x)));
return parents.get(x);
}
// 合并,把y作为x的parents
void union(int x, int y) {
if (parents.containsKey(y)) {
parents.put(x, y);
}
}
}
/**
* 哈希表 + 并查集 (「单向链表」转换成了「树」)
* 耗时47ms,内存消耗61.3MB
* @param nums 集合



**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://gitee.com/vip204888)**