网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
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 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 集合
* @return 最长序列
*/
private static int longestConsecutive(int[] nums) {
if (nums.length <= 1) {
return nums.length;
}
int longestLen = 0;
UnionFind uf = new UnionFind(nums);
for (int i = 0; i < nums.length; i++) {
uf.union(nums[i], nums[i] + 1);
}
for (int i = 0; i < nums.length; i++) {
longestLen = Math.max(longestLen, uf.find(nums[i]) - nums[i] + 1);
}
return longestLen;
}
并查集的步骤主要有:初始化 ——> 查找 ——> 合并
1、初始化如下图,fa[]存储每个元素的父节点,初始化时每个父节点设置为自己。
![](https://img-blog.csdnimg.cn/540815c39614422a9c4700c2b718847a.png)
2、查找如下图,找到i的祖先;
![](https://img-blog.csdnimg.cn/7e7eecd8369e4a45a4a8e92d1a3497a6.png)
3、合并如下图,i的祖先指向j的祖先
![](https://img-blog.csdnimg.cn/5e6d1ea865d740cd81e79d677c932391.png)
最后将一些不相干的集合进行了合并。另外如果要进行路径压缩,则find函数查找祖先元素进行了路径压缩。
![](https://img-blog.csdnimg.cn/f99c0c4ec2be4ab2ba8f91912fb7ec5b.png)
>
> 备注:如果觉得写的有问题敬请指出,请大家以自己的判断力来了解并查集算法,毕竟我也是初步了解阶段,在此记录一下学习过程。
>
![img](https://img-blog.csdnimg.cn/img_convert/ce7188489d93d7c594d4c671aff04c06.png)
![img](https://img-blog.csdnimg.cn/img_convert/4f0d7b96c8dbe74ad51ecb6d0fa014fe.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**