首页 > 其他分享 >【LeetCode】收集树中金币

【LeetCode】收集树中金币

时间:2023-09-22 10:24:03浏览次数:43  
标签:coins 节点 金币 edges 树中 LeetCode append deg

链接
题目

给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 。给你整数 n 和一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] = [ai, bi] 表示树中节点 ai 和 bi 之间有一条边。再给你一个长度为 n 的数组 coins ,其中 coins[i] 可能为 0 也可能为 1 ,1 表示节点 i 处有一个金币。

一开始,你需要选择树中任意一个节点出发。你可以执行下述操作任意次:

收集距离当前节点距离为 2 以内的所有金币,或者
移动到树中一个相邻节点。
你需要收集树中所有的金币,并且回到出发节点,请你返回最少经过的边数。

如果你多次经过一条边,每一次经过都会给答案加一。

思路:看灵神的题解
将没有金币的叶节点全部干掉

因为最后收集完要回到起始点,所以相当于走过的路径又走了一遍
我们最后直接统计需要走的路径数,再*2就ok
代码如下

class Solution:
    def collectTheCoins(self, coins: List[int], edges: List[List[int]]) -> int:
        n = len(coins)
        # 构造图
        g = [[] for _ in range(n)]
        for x, y in edges:
            g[x].append(y)
            g[y].append(x)
        # 得到每个点的度数
        deg = list(map(len, g))
        left_edges = n - 1
        q = []
        for i, (d, c) in enumerate(zip(deg, coins)):
            # 找到没有金币的叶节点,
            if d == 1 and c == 0:
                q.append(i)
        # 将其删除,直至删除完毕
        while q:
            left_edges -= 1
            for y in g[q.pop()]:
                deg[y] -= 1
                if deg[y] == 1 and coins[y] == 0:
                    q.append(y)
        # 找出所有有金币的叶子节点
        for i, (d, c) in enumerate(zip(deg, coins)):
            if d == 1 and c:
                q.append(i)
        left_edges -= len(q)
        # 遍历所有有金币的叶子节点
        for x in q:
            for y in g[x]:
                deg[y] -= 1
                if deg[y] == 1:
                    left_edges -= 1
        return max(left_edges * 2, 0)

标签:coins,节点,金币,edges,树中,LeetCode,append,deg
From: https://www.cnblogs.com/basilicata/p/17721679.html

相关文章

  • "金币写作"
    百度搜索时看到的一个热搜词,第一次看到这个概念。为了SEO,人们会做很多内容曲折的写作,比如百度知道就有很多。如何避免这种情形?我将设法避免我的产品中出现”金币写作“。 当互联网充斥着大量的”金币写作“现象时,文学领域会出现哪些现象?......
  • LC2603 收集树中金币
    利用了拓扑排序思想的趣题。答案要求统计“走过的边数”,这个不是很好统计,但是统计“哪些点不需要去”比较简单:没有金币的子树不需要去;删去1之后的叶子结点不需要去;删去1,2之后的叶子结点不需要去。可以证明,其他的点都需要去到。删去上述结点的依据是度数(都是叶子结点)......
  • Leetcode刷题448.找到所有数组中消失的数字
    给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1,n] 内。请你找出所有在 [1,n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。 示例1:输入:nums=[4,3,2,7,8,2,3,1]输出:[5,6]示例2:输入:nums=[1,1]输出:[2] 提示:n==nums.lengt......
  • Leetcode刷题283.移动零
    给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。请注意 ,必须在不复制数组的情况下原地对数组进行操作。 示例1:输入:nums=[0,1,0,3,12]输出:[1,3,12,0,0]示例2:输入:nums=[0]输出:[0] 提示:1<=nums.length<......
  • LeetCode53.最大子数组和
    要求最大连续子数组的和,可以这样考虑,比如现在我想求下标 i~j,i<j 这一范围内子数组的和,那么我可以分别先求出 0~i-1 范围和 0~j 范围两个子数组的和,可得Sum[i~j]=Sum[0~j]-Sum[0~i-1] ,这就是本题解法的核心思想。解法详细描述:先从下标0开始,遍历 nums 数组,求出到当前下标......
  • 124. 二叉树中的最大路径和
    二叉树中的路径被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中至多出现一次。该路径至少包含一个节点,且不一定经过根节点。路径和是路径中各节点值的总和。给你一个二叉树的根节点root,返回其最大路径和。示例1:输入:root=......
  • leetcode 22 括号生成
    数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。示例1:输入:n=3输出:["((()))","(()())","(())()","()(())","()()()"]示例2:输入:n=1输出:["()"]提示:1<=n<=8  //这种用例很可能就是递归代码:classSolut......
  • 【LeetCode】LCP 06. 拿硬币
    描述桌上有​​n​​​堆力扣币,每堆的数量保存在数组​​coins​​中。我们每次可以选择任意一堆,拿走其中的一枚或者两枚,求拿完所有力扣币的最少次数。示例输入:​​[4,2,1]​​输出:​​4​​解释:第一堆力扣币最少需要拿2次,第二堆最少需要拿1次,第三堆最少需要拿1次,......
  • #yyds干货盘点# LeetCode程序员面试金典:二叉搜索树的最近公共祖先
    题目:给定一个二叉搜索树,找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树T的两个结点p、q,最近公共祖先表示为一个结点x,满足x是p、q的祖先且x的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉搜索树: root= [6,2......
  • #yyds干货盘点# LeetCode程序员面试金典:建立四叉树
    1.简述:给你一个 n*n 矩阵 grid ,矩阵由若干 0 和 1 组成。请你用四叉树表示该矩阵 grid 。你需要返回能表示矩阵 grid 的四叉树的根结点。四叉树数据结构中,每个内部节点只有四个子节点。此外,每个节点都有两个属性:val:储存叶子结点所代表的区域的值。1对应 True,0对......