3558.给边赋权值的方案数 I:广度优先搜索+数学(一看就懂,无复杂推导)
【LetMeFly】3558.给边赋权值的方案数 I:广度优先搜索+数学(一看就懂,无复杂推导)
力扣题目链接:https://leetcode.cn/problems/number-of-ways-to-assign-edge-weights-i/
给你一棵 n 个节点的无向树,节点从 1 到 n 编号,树以节点 1 为根。树由一个长度为 n - 1 的二维整数数组 edges 表示,其中 edges[i] = [ui, vi] 表示在节点 ui 和 vi 之间有一条边。
一开始,所有边的权重为 0。你可以将每条边的权重设为 1 或 2。
两个节点 u 和 v 之间路径的 代价 是连接它们路径上所有边的权重之和。
选择任意一个 深度最大 的节点 x。返回从节点 1 到 x 的路径中,边权重之和为 奇数 的赋值方式数量。
由于答案可能很大,返回它对 109 + 7 取模的结果。
注意: 忽略从节点 1 到节点 x 的路径外的所有边。
示例 1:

输入: edges = [[1,2]]
输出: 1
解释:
- 从节点 1 到节点 2 的路径有一条边(
1 → 2)。 - 将该边赋权为 1 会使代价为奇数,赋权为 2 则为偶数。因此,合法的赋值方式有 1 种。
示例 2:

输入: edges = [[1,2],[1,3],[3,4],[3,5]]
输出: 2
解释:
- 最大深度为 2,节点 4 和节点 5 都在该深度,可以选择任意一个。
- 例如,从节点 1 到节点 4 的路径包括两条边(
1 → 3和3 → 4)。 - 将两条边赋权为 (1,2) 或 (2,1) 会使代价为奇数,因此合法赋值方式有 2 种。
提示:
2 <= n <= 105edges.length == n - 1edges[i] == [ui, vi]1 <= ui, vi <= nedges表示一棵合法的树。
解题方法:BFS+数学
这道题分为两个部分:
- 求出这棵树的最大深度
- n条边和为奇数的方案数(每条边是1或2)
关于怎么求出这棵树的最大深度,很多人都用的深度优先搜索(DFS),我这里用下广度优先搜索(BFS),效果和时空复杂度是一样的。
剩下是n条边,每条边选1或2,使得总和为奇数,方案数有多少?
这里根本不需要二项式定理! 其实换个角度,先让$n-1$条边任选,总共有$2^{n-1}$种选法。如果$n-1$条边总和为奇数,那么剩下那条边选$2$;如果$n-1$条边总和为偶数,那么剩下那条边选$1$就好了。
也就是说,如果从根节点到最深的节点共有$n$条边,那么返回$2^{n-1}$即为所求。
这里$2^{n-1}$可以使用快速幂也可以直接暴力计算就好。
- 时间复杂度$O(n)$
- 空间复杂度$O(n)$
AC代码
C++
1 | |
同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~
千篇源码题解已开源