剑指offer_II_119 最长连续序列_uf = new newunionfind(len(nums))

27 阅读3分钟
    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 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://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/a3f249ed4d8a4dd78219f28ec1c49080~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262538&x-signature=AVT1yQKF0P8%2Fl8%2BGZZ7nk4Rd5ns%3D)


2、查找如下图,找到i的祖先;


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/d371664bcd4641b498e59e167284c1c1~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262538&x-signature=BXmJlJZZeFgPsVzve61inHRBPDo%3D)


 3、合并如下图,i的祖先指向j的祖先


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/a1ae63da07134f70aa4a27bc32181c3a~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262538&x-signature=lap4QoPFvjNuYpp5DyFGfFtNZUI%3D)


最后将一些不相干的集合进行了合并。另外如果要进行路径压缩,则find函数查找祖先元素进行了路径压缩。


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/754367ba34e14521a8a57e28434783b2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262538&x-signature=H3PTOXKgpqBk%2BYrXRZfHMK9%2BT54%3D)



> 
> 备注:如果觉得写的有问题敬请指出,请大家以自己的判断力来了解并查集算法,毕竟我也是初步了解阶段,在此记录一下学习过程。
> 
> 
> 



并查集参考文献:


1、[并查集算法详解 - 知乎](https://gitee.com/vip204888)


2、[并查集从入门到出门 - 力扣(LeetCode)](https://gitee.com/vip204888)


3、[图论——并查集(详细版)\_哔哩哔哩\_bilibili](https://gitee.com/vip204888)_哔哩哔哩_bilibili")


![img](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/1fdf48f04b294758be27f9636adbaaf9~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262538&x-signature=Ig9HgAte%2BDLrEjkg7G7jz%2FuFtsc%3D)
![img](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/d2a6c076fb4c40bc95b3feb218cb5b6e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771262538&x-signature=kzKvPDJzESwYi6Ly%2B6t7ZlvOAoM%3D)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://gitee.com/vip204888)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**