首页 > 其他分享 >LeetCode力扣——并查集:947. 移除最多的同行或同列石头,1971. 寻找图中是否存在路径,2424. 最长上传前缀

LeetCode力扣——并查集:947. 移除最多的同行或同列石头,1971. 寻找图中是否存在路径,2424. 最长上传前缀

时间:2024-09-22 21:48:43浏览次数:3  
标签:parent int 947 查集 find 移除 上传 节点 adj

947. 移除最多的同行或同列石头

题目描述

947. 移除最多的同行或同列石头

n 块石头放置在二维平面中的一些整数坐标点上。每个坐标点上最多只能有一块石头。

如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头。

给你一个长度为 n 的数组 stones ,其中 stones[i] = [xi, yi] 表示第 i 块石头的位置,返回 可以移除的石子 的最大数量。

运行代码

class Solution {
    public int removeStones(int[][] stones) {
        int n = stones.length;
        List<Integer>[] adj = new List[n];
        boolean[] visited = new boolean[n];
        for (int i = 0; i < n; i++) {
            adj[i] = new ArrayList<>();
        }
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (sameRowOrCol(stones[i], stones[j])) {
                    adj[i].add(j);
                    adj[j].add(i);
                }
            }
        }
        int remain = 0;
        for (int i = 0; i < n; i++) {
            if (!visited[i]) {
                remain++;
                explore(i, adj, visited);
            }
        }
        return n - remain;
    }

    private boolean sameRowOrCol(int[] a, int[] b) {
        return a[0] == b[0] || a[1] == b[1];
    }

    private void explore(int curr, List<Integer>[] adj, boolean[] visited) {
        if (visited[curr]) return;
        visited[curr] = true;
        for (int next : adj[curr]) {
            explore(next, adj, visited);
        }
    }
}

代码思路

一、整体功能

这段代码的目的是计算在给定二维平面上的一系列点(由整数坐标表示)中,可以移除的点的最大数量,使得剩下的点无法通过水平或垂直方向与其他点相连。

二、主要方法分析

  1. removeStones方法:

    • remain初始化为 0,用于记录最终剩下的无法通过水平或垂直方向与其他点相连的点的数量。
    • 创建一个boolean[] visited数组,用于标记每个点是否被访问过。长度也为点的总数。
    • 创建一个List<Integer>[] adj数组,用于存储每个点的相邻点列表。这个数组的长度与点的总数相同。
    • n表示输入的二维数组stones的长度,也就是点的总数。
    • 构建相邻点列表:通过两层嵌套循环遍历所有的点对。如果两个点在同一行或同一列(通过sameRowOrCol方法判断),则将它们互相添加到对方的相邻点列表中。
    • 深度优先搜索计算剩余点的数量:通过循环遍历所有的点,如果一个点没有被访问过,则将remain加一,并从这个点开始进行深度优先搜索(调用explore方法)。最后返回可以移除的点的数量,即总点数n减去剩余点的数量remain
  2. sameRowOrCol方法:接收两个点的坐标数组ab,判断这两个点是否在同一行(横坐标相同)或同一列(纵坐标相同),如果是则返回true,否则返回false

  3. explore方法:接收当前点的索引curr、相邻点列表数组adj和访问标记数组visited。如果当前点已经被访问过,则直接返回。将当前点标记为已访问。遍历当前点的相邻点列表,对每个未访问的相邻点递归调用explore方法进行深度优先搜索。

1971. 寻找图中是否存在路径

题目描述

1971. 寻找图中是否存在路径

有一个具有 n 个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1(包含 0 和 n - 1)。图中的边用一个二维整数数组 edges 表示,其中 edges[i] = [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接,并且没有顶点存在与自身相连的边。

请你确定是否存在从顶点 source 开始,到顶点 destination 结束的 有效路径 。

给你数组 edges 和整数 nsource 和 destination,如果从 source 到 destination 存在 有效路径 ,则返回 true,否则返回 false 。

运行代码

class Solution {
    public boolean validPath(int n, int[][] edges, int source, int destination) {
        int[] parent = new int[n];
        for (int i = 0; i < n; i++) {
            parent[i] = i;
        }
        for (int[] edge : edges) {
            union(edge[0], edge[1], parent);
        }
        return find(source, parent) == find(destination, parent);
    }

    private int find(int x, int[] parent) {
        return parent[x] == x? x : (parent[x] = find(parent[x], parent));
    }

    private void union(int x, int y, int[] parent) {
        int rootX = find(x, parent);
        int rootY = find(y, parent);
        if (rootX!= rootY) {
            parent[rootX] = rootY;
        }
    }
}

代码思路

  1. validPath方法:

    • 初始化变量:创建一个整数数组p,用于存储每个节点的父节点。这里使用了并查集的数据结构来判断节点之间的连通性。首先将数组p初始化为每个节点的父节点都是自身,表示每个节点最初都在不同的集合中。
    • 合并节点集合:遍历输入的边列表edges,对于每条边[u, v],通过调用find方法找到uv的代表元素(即所在集合的根节点),然后将其中一个代表元素的父节点设置为另一个代表元素,实现两个集合的合并。
    • 判断路径是否存在:最后,通过调用find方法找到源节点source和目标节点destination的代表元素,如果它们相同,则说明源节点和目标节点在同一个集合中,即存在一条路径连接它们,返回true;否则返回false
  2. find方法:

    • 这个方法实现了并查集中的查找操作,用于找到一个节点所在集合的代表元素(根节点)。
    • 如果一个节点的父节点就是它自己,那么它就是所在集合的代表元素,直接返回该节点。
    • 如果一个节点的父节点不是它自己,那么递归地调用find方法找到它的父节点的代表元素,并在返回之前将该节点的父节点设置为找到的代表元素,这一步叫做路径压缩,可以加快后续的查找操作。

2424. 最长上传前缀

题目描述

2424. 最长上传前缀

给你一个 n 个视频的上传序列,每个视频编号为 1 到 n 之间的 不同 数字,你需要依次将这些视频上传到服务器。请你实现一个数据结构,在上传的过程中计算 最长上传前缀 。

如果 闭区间 1 到 i 之间的视频全部都已经被上传到服务器,那么我们称 i 是上传前缀。最长上传前缀指的是符合定义的 i 中的 最大值 。

请你实现 LUPrefix 类:

  • LUPrefix(int n) 初始化一个 n 个视频的流对象。
  • void upload(int video) 上传 video 到服务器。
  • int longest() 返回上述定义的 最长上传前缀 的长度。

运行代码

class LUPrefix {
    private int x;
    private java.util.Set<Integer> s;

    public LUPrefix(int n) {
        x = 1;
        s = new java.util.HashSet<>();
    }

    public void upload(int video) {
        s.add(video);
    }

    public int longest() {
        while (s.contains(x)) {
            x++;
        }
        return x - 1;
    }
}

代码思路

  1. 构造函数LUPrefix(int n):初始化变量:将x初始化为 1,表示当前最长上传前缀的下一个期望视频编号。创建一个HashSet<Integer>类型的集合s,用于存储已经上传的视频编号。

  2. upload(int video)方法:功能:这个方法用于将指定编号的视频标记为已上传,即将视频编号添加到集合s中。

  3. longest()方法:

    • 循环查找:通过一个while循环,不断检查当前的x是否在集合s中。如果在集合中,说明视频编号为x的视频已经上传,此时将x的值增加 1,继续检查下一个编号。
    • 确定最长上传前缀:当x不在集合s中时,循环停止。此时x - 1就是最长上传前缀的长度。这是因为在循环停止时,x是第一个未上传的视频编号,所以最长上传前缀就是x - 1

标签:parent,int,947,查集,find,移除,上传,节点,adj
From: https://blog.csdn.net/u014114223/article/details/142358034

相关文章

  • 基础带权并查集
    只能基础查询到根节点的距离structDSU{intfa[N],siz[N],deep[N];voidinit(){for(inti=1;i<=n;i++){fa[i]=i;siz[i]=1;deep[i]=0;}}intfind(intx){inttmpfa=fa[x];......
  • 移除链表元素
    移除链表元素思路:1.首先判断链表是否为空,若为空直接返回head(null)2.若链表不为空,让prev记住要删除节点的前一个位置,cur指向要删除的元素位置,若cur指向的val==要删除的值,就让prev.next指向cur.next3.因为cur是从head的下一个节点位置开始判断的,就没有判断头节点是否为要......
  • 2024牛客多校 4 (概率,带权并查集,构造)
    2024牛客多校4(概率,带权并查集,构造)J-Zero题面:给出整数\(n\)和\(k\),一个01?字符串\(s\)。?有概率是0或是1,且概率相等,一段区间\([l,r]\)的贡献这样计算:这一段区间不包含0贡献为长度的\(k\)次方求这个字符串\(s\)的期望贡献是多少?solution:首......
  • Elasticsearch 分片迁移与移除集群节点操作
    Elasticsearch分片迁移与移除集群节点操作问题背景在单台服务器上部署了7个Elasticsearch节点,分别为es-node1到es-node7,端口从9201到9207。每个节点都承载大量数据,但没有设置副本分片。由于多个节点共享同一台服务器的硬件资源,复杂查询时会导致CPU占用率达到......
  • 27. 移除元素
    题目描述:给你一个数组nums和一个值val,你需要原地移除所有数值等于val的元素。元素的顺序可能发生改变。然后返回nums中与val不同的元素的数量。假设nums中不等于val的元素数量为k,要通过此题,您需要执行以下操作:更改nums数组,使nums的前k个元素包含不等于......
  • 代码随想录Day3 | LeetCode 203. 移除链表元素、LeetCode 707. 设计链表、LeetCode 20
    LeetCode203.移除链表元素链表基础概念题,也可以用递归做,不过我们把递归的思想放在更能体现它的LeetCode206.反转链表#Definitionforsingly-linkedlist.#classListNode:#def__init__(self,val=0,next=None):#self.val=val#self.next......
  • 代码随想录算法训练营第一天|704二分查找 27移除数组 977.有序数组的平方
    704二分查找给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。示例1:输入:nums=[-1,0,3,5,9,12],target=9输出:4解释:9出现在nums中并且下标为4示例 2:输......
  • 代码随想录算法训练营第三天|203移除链表元素 707设计链表 206反转链表
    203.移除链表元素题意:删除链表中等于给定值val的所有节点。示例1:输入:head=[1,2,6,3,4,5,6],val=6输出:[1,2,3,4,5]示例2:输入:head=[],val=1输出:[]示例3:输入:head=[7,7,7,7],val=7输出:[]链表一直是处理的不太好的数据结构,太久没处理过,第一次做......
  • 九、并查集-算法总结
    文章目录九、并查集9.1简介9.2数据结构9.2.1初始化9.2.2Quick-Find9.2.3Quick-Union9.2.4WeightedQuickUnion九、并查集9.1简介并查集用于处理不相交集合的合并与查询问题,常见操作有:查询:查询元素属于哪个集合,可用于判断元素是否在一个集合中合并:合并两......
  • LeetCode 2390. 从字符串中移除星号(字符串、栈)
    题目:2390.从字符串中移除星号思路:使用栈就可以,这里string也可以实现栈的效果classSolution{public:stringremoveStars(strings){stringe="";for(autox:s){if(x=='*')e.pop_back();elsee.push_back(x);......