leetcode 2421. Number of Good Paths(python)

leetcode 2421. Number of Good Paths(python)

描述

There is a tree (i.e. a connected, undirected graph with no cycles) consisting of n nodes numbered from 0 to n - 1 and exactly n - 1 edges. You are given a 0-indexed integer array vals of length n where vals[i] denotes the value of the ith node. You are also given a 2D integer array edges where edges[i] = [ai, bi] denotes that there exists an undirected edge connecting nodes ai and bi.

A good path is a simple path that satisfies the following conditions:

  • The starting node and the ending node have the same value.
  • All nodes between the starting node and the ending node have values less than or equal to the starting node (i.e. the starting node’s value should be the maximum value along the path).

Return the number of distinct good paths.

Note that a path and its reverse are counted as the same path. For example, 0 -> 1 is considered to be the same as 1 -> 0. A single node is also considered as a valid path.

Example 1:

Input: vals = [1,3,2,1,3], edges = [[0,1],[0,2],[2,3],[2,4]]
Output: 6
Explanation: There are 5 good paths consisting of a single node.
There is 1 additional good path: 1 -> 0 -> 2 -> 4.
(The reverse path 4 -> 2 -> 0 -> 1 is treated as the same as 1 -> 0 -> 2 -> 4.)
Note that 0 -> 2 -> 3 is not a good path because vals[2] > vals[0].

Example 2:

Input: vals = [1,1,2,2,3], edges = [[0,1],[1,2],[2,3],[2,4]]
Output: 7
Explanation: There are 5 good paths consisting of a single node.
There are 2 additional good paths: 0 -> 1 and 2 -> 3.

Example 3:

Input: vals = [1], edges = []
Output: 1
Explanation: The tree consists of only one node, so there is one good path.

Note:

  • n == vals.length
  • 1 <= n <= 3 * 10^4
  • 0 <= vals[i] <= 10^5
  • edges.length == n - 1
  • edges[i].length == 2
  • 0 <= ai, bi < n
  • ai != bi
  • edges represents a valid tree.

解析

根据题意,有一棵树由 n 个节点组成,编号从 0 到 n - 1 ,正好有 n - 1 条边。给定一个长度为 n 的 0 索引的整数数组 vals ,其中 vals[i] 表示第 i 个节点的值。另外给出一个二维整数数组 edges ,其中 edges[i] = [ai, bi] 表示存在连接节点 ai 和 bi 的无向边。

一条好的路径得满足以下条件:

  • 起始节点和结束节点具有相同的值。
  • 起始节点和结束节点之间的所有节点的值都小于或等于起始节点,即起始节点的值应为路径上的最大值。

返回不同良好路径的数量。请注意,路径与其反向路径被认为是同一路径。例如,0 -> 1 被视为与 1 -> 0 相同。单个节点也被视为有效路径。

这道题我也是看了大佬的讲解才想明白的,主要思路就是将这个树的问题转换成了图的问题,使用了并查集来解决该题。

最开始我们将这棵树中的节点都单独拿出来,想象他们彼此都是没有联系的,此时也就是一个有 N 个节点的没有互相联系的图,此时已经有 N 条有用的路径出现了,加入到 result 中,也就是每个节点自身。然后由于每个有用的路径都是起始节点相同且大于等于中间的节点值,所以我们在图中最先找出现值最小的节点 x ,这样可以始终保证连通块的代表元的节点值是最大的。对于节点 x 及其邻居 y ,如果 y 所处的连通分量的最大节点值不超过 vals[x] ,那么可以把 y 所处的连通块合并到 x 所处的连通块中。如果此时这两个连通块的最大节点值相同,那么可以根据乘法原理,把这两个连通块内的等于最大节点值的节点个数相乘,加到答案 result 中,不断遍历累积计算最终得到结果。

时间复杂度为 O(NlogN) ,空间复杂度为 O(N)。

解答

class Solution(object):
    def numberOfGoodPaths(self, vals, edges):
        """
        :type vals: List[int]
        :type edges: List[List[int]]
        :rtype: int
        """
        def find(x):
            if father[x] != x:
                father[x] = find(father[x])
            return father[x]

        n = len(vals)
        graph = [[] for _ in range(n)]
        for x, y in edges:
            graph[x].append(y)
            graph[y].append(x)
        father = list(range(n))
        L = [1] * n
        result = n
        for val, x in sorted(zip(vals, range(n))):
            father_x = find(x)
            for y in graph[x]:
                y = find(y)
                if y == father_x or vals[y] > val:
                    continue
                if vals[y] == val:
                    result += L[father_x] * L[y]
                    L[father_x] += L[y]
                father[y] = father_x
        return result

运行结果

Runtime 1715 ms,Beats 88.69%
Memory 53.3 MB,Beats 18.35%

原题链接

https://leetcode.com/problems/number-of-good-paths/description/

您的支持是我最大的动力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王大丫丫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值