LeetCode_拓扑排序_困难_2603.收集树中金币

2023-09-22 10:00:28

1.题目

给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 。给你整数 n 和一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] = [ai, bi] 表示树中节点 ai 和 bi 之间有一条边。再给你一个长度为 n 的数组 coins ,其中 coins[i] 可能为 0 也可能为 1,1 表示节点 i 处有一个金币。一开始,你需要选择树中任意一个节点出发。你可以执行下述操作任意次:

  • 收集距离当前节点距离为 2 以内的所有金币,或者
  • 移动到树中一个相邻节点。

你需要收集树中所有的金币,并且回到出发节点,请你返回最少经过的边数。如果你多次经过一条边,每一次经过都会给答案加一。

示例 1:
在这里插入图片描述

输入:coins = [1,0,0,0,0,1], edges = [[0,1],[1,2],[2,3],[3,4],[4,5]]
输出:2
解释:从节点 2 出发,收集节点 0 处的金币,移动到节点 3 ,收集节点 5 处的金币,然后移动回节点 2。

示例 2:

在这里插入图片描述

输入:coins = [0,0,0,1,1,0,0,1], edges = [[0,1],[0,2],[1,3],[1,4],[2,5],[5,6],[5,7]]
输出:2
解释:从节点 0 出发,收集节点 4 和 3 处的金币,移动到节点 2 处,收集节点 7 处的金币,移动回节点 0 。

提示:
n == coins.length
1 <= n <= 3 * 104
0 <= coins[i] <= 1
edges.length == n - 1
edges[i].length == 2
0 <= ai, bi < n
ai != bi
edges 表示一棵合法的树。

2.思路

(1)两次拓扑排序
思路参考本题官方题解

3.代码实现(Java)

//思路1————两次拓扑排序
class Solution {
    public int collectTheCoins(int[] coins, int[][] edges) {
        int n = coins.length;
        //图的邻接表
        List<Integer>[] graph = new ArrayList[n];
        for (int i = 0; i < n; ++i) {
            graph[i] = new ArrayList<>();
        }
        //计算每个节点的度
        int[] degree = new int[n];
        for (int[] edge : edges) {
            int x = edge[0], y = edge[1];
            graph[x].add(y);
            graph[y].add(x);
            ++degree[x];
            ++degree[y];
        }
        //将入度为 1 且无金币的叶子节点放入队中
        Queue<Integer> queue = new ArrayDeque<>();
        for (int i = 0; i < n; ++i) {
            if (degree[i] == 1 && coins[i] == 0) {
                queue.offer(i);
            }
        }
        int rest = n;
        while (!queue.isEmpty()) {
            int u = queue.poll();
            --degree[u];
            --rest;
            for (int v : graph[u]) {
                --degree[v];
                if (degree[v] == 1 && coins[v] == 0) {
                    queue.offer(v);
                }
            }
        }
        //删除树中所有的叶子节点,连续删除 2 次
        for (int x = 0; x < 2; ++x) {
            queue = new ArrayDeque<Integer>();
            for (int i = 0; i < n; ++i) {
                if (degree[i] == 1) {
                    queue.offer(i);
                }
            }
            while (!queue.isEmpty()) {
                int u = queue.poll();
                --degree[u];
                --rest;
                for (int v : graph[u]) {
                    --degree[v];
                }
            }
        }
        return rest == 0 ? 0 : (rest - 1) * 2;
    }
}
更多推荐

httpclient3.1跳过ssl验证

原来的老项目调用一个Http的服务,最近http的服务调整成了https,因此需要调整一下,网上大部分都是4.5以上版本,3.1版本处理方法比较少,因此记录一下一、实现两个类1.MyX509TrustManagerimportjava.security.cert.CertificateException;importj

SSL加速是什么,有什么优势?

SSL加速技术是一种专门用于加速HTTPS通信的技术,它可以在服务器和客户端之间提供高效的加密和解密处理,以提升网络通信的安全性和性能。以下是SSL加速技术的一些主要优势:提高网站的访问速度:SSL加速技术可以对SSL握手过程进行优化,加快SSL连接速度,从而减少响应时间和延迟,提高网站的访问速度。降低服务器负载:SS

Nacos注册中心

Nacos安装https://nacos.io/zh-cn/源码安装第一步:利用Gitee获取nacos在github上的代码到自己的gitee仓库中https://github.com/alibaba/nacos.git第二步:下载源码到本地。第三步:使用maven编译代码。#先切换到master分支gitcheck

git及dbc的学习

1)git的使用方法CommandlineinstructionsYoucanalsouploadexistingfilesfromyourcomputerusingtheinstructionsbelow.Gitglobalsetupgitconfig--globaluser.name"username"gitcon

redis分布式锁

用于用户重复注册,点击过快,有可能会注册相同的手机号问题。给用户手机号枷锁一分钟时间,判断相同的手机号。判断下面这块代码执行时间是否超过一分钟时间,不论超没超过都会释放锁,下个同样的手机号再次注册,都得等到代码执行完毕后(或者是一分钟后)才能进行注册,防止有两个相同的手机号,两个线程,查询数据库都没存在,而注册了两次,

竞赛选题 基于机器视觉的银行卡识别系统 - opencv python

1前言🔥优质竞赛项目系列,今天要分享的是基于深度学习的银行卡识别算法设计该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!🧿更多资料,项目分享:https://gitee.com/dancheng-senior/postgraduate2算法设计流程银行卡卡号识别技术原理是先对银行卡图像定位,保障获取图像绝对位置

SpringSecurity---内存认证和数据库认证

目录一、内存认证二、认证逻辑三、数据库认证(也就是用户名和密码在数据库中寻找)(1)mapper层(2)启动类添加扫描注解(3)编写UserDetailsService实现类一、内存认证@ConfigurationpublicclassSecurityConfig{//定义认证逻辑@BeanpublicUserDeta

springboot整合mybatis

整合SpringBoot与MyBatis框架的步骤如下:步骤1:创建SpringBoot项目-在IDE中创建一个新的SpringBoot项目。步骤2:添加相关依赖-在项目的pom.xml文件中添加以下依赖:<dependencies><dependency><groupId>org.springframework.bo

基于PHP的短视频SEO矩阵系统源码开发

随着短视频市场的爆发式增长,越来越多的企业开始寻求在短视频领域建立自己的品牌形象,增加用户粘性和获取更多流量。为此,一套高效的短视频SEO矩阵系统源码显得尤为重要。本文将介绍基于PHP语言的短视频SEO矩阵系统源码开发,帮助读者更好地了解该系统的实现原理和开发过程。一、系统概述短视频SEO矩阵系统是一套基于PHP语言开

千万级用户的大型网站,如何进行服务器压力预估?

前言:一般情况下,单台Tomcat服务器每秒支撑500请求,单台MySQL数据库每秒支撑5000左右的请求,单台Redis缓存支撑每秒几万请求。1、千万级用户量的压力预估假设大型网站预估用户数是1000万,那么根据28法则,每天会来访问这个网站的用户占到20%,也就是200万用户每天会过来访问。通常假设平均每个用户每次

Linux 文件权限基础:文件和目录权限管理指南

文章目录Linux文件权限基础1.引言1.1什么是文件权限1.2文件权限的重要性2.Linux文件权限基础2.1Linux文件系统简介2.2文件和目录的属性2.3权限类型:读、写和执行2.4所有者、组和其他用户2.5权限符号表示法:r、w、x和-2.6使用ls-l命令查看文件权限3.修改文件权限3.1使用chmod命令

热文推荐