88开元娱乐-最好的游戏大厅

2025-12-07: 使叶子路径成本相等的最小增量。用go语言, 给出一个
88开元娱乐-最好的游戏大厅
你的位置:88开元娱乐-最好的游戏大厅 > 新闻动态 > 2025-12-07: 使叶子路径成本相等的最小增量。用go语言, 给出一个
2025-12-07: 使叶子路径成本相等的最小增量。用go语言, 给出一个
发布日期:2025-12-15 15:00    点击次数:174

2025-12-07:使叶子路径成本相等的最小增量。用go语言,给出一个整数 n 和一棵以节点 0 为根的树(节点编号 0 到 n−1)。树用长度为 n−1 的边数组 edges 表示,其中 edges[i] = [u_i, v_i] 表示节点 u_i 与 v_i 相连。每个节点 i 关联一个代价 cost[i],一条路径的“权重”定义为路径上所有节点代价的和。

允许你对任意若干节点各自增加一个不小于 0 的数(不同节点的增量可以不同);如果某节点增加的值为 0,则视为未改变。目标是通过这样的增量使得从根 0 到所有叶子节点的路径权重都相等。请返回需要被增大的节点的最小数量。

2

edges.length == n - 1。

edges[i] == [ui, vi]。

0

cost.length == n。

1

输入保证 edges 表示一棵合法的树。

输入: n = 3, edges = [[0,1],[0,2]], cost = [2,1,3]。

输出: 1。

解释:

树中有两条从根到叶子的路径:

路径 0 → 1 的得分为 2 + 1 = 3。

路径 0 → 2 的得分为 2 + 3 = 5。

为了使所有路径的得分都等于 5,可以将节点 1 的成本增加 2。

仅需增加一个节点的成本,因此输出为 1。

题目来自力扣3593。

大体步骤

1. 构建树的邻接表

代码首先根据输入的边数组 edges 构建了一个邻接表 g,用于表示树的结构。这是一个无向图,因此每条边都会在邻接表中为两个节点相互添加连接。特别地,代码为根节点0额外添加了一个指向-1的边,这是为了避免在后续处理中将根节点误判为叶子节点。

2. 深度优先搜索(DFS)与贪心调整

核心逻辑在 dfs 函数中,它采用后序遍历(先处理子节点,再处理当前节点)的方式自底向上地计算和调整路径成本。

• 叶子节点处理:当一个节点是叶子节点时(在邻接表中除了父节点只有一个连接),它到根节点的路径成本就是其自身的 cost。DFS函数会直接返回这个成本值。

• 非叶子节点处理:对于非叶子节点,DFS会递归地处理其所有子节点,并收集每个子节点传递上来的、从该子节点到其下属叶子节点的最大路径成本(mx)。

• 寻找最大成本与计数:在处理当前节点的所有子节点时,算法会追踪遇到的最大路径成本 maxS,并记录有多少个子节点能提供这个最大成本(cnt)。这个过程确保了算法能识别出当前节点子树下“最长”的路径。

• 贪心决策与计数:关键的贪心策略在于,为了让所有从当前节点出发到叶子节点的路径成本相等,只需要让那些路径成本较小的子节点向最大的路径成本看齐。具体实现上,算法不会去实际修改节点的 cost 值,而是通过计算需要增加成本的节点数量来解决问题。公式 ans += len(g[x]) - 1 - cnt 的含义是:

len(g[x]) - 1:当前节点 x 拥有的有效子节点数量(因为邻接表中包含指向父节点的边,需要减去)。

cnt:已经拥有最大路径成本的子节点数量。

两者之差,就是那些路径成本不是最大的子节点数量。对于这些子节点所在的路径,我们需要通过增加其中某个节点的成本来提升整条路径的成本。这个“某个节点”的调整可以等效地上推到当前节点 x 的子节点上。因此,这个差值就是在当前节点层面,需要执行成本增加的节点数量。

• 返回路径成本:最后,DFS函数返回从当前节点 x 到其叶子节点的最大路径成本,即 maxS + cost[x]。这个值将提供给 x 的父节点用于计算。

3. 算法启动

从根节点0开始调用DFS,初始的父节点设为-1。DFS遍历完整棵树后,累加器 ans 中存储的值就是所需的最小增量节点数量,将其返回。

复杂度分析

时间复杂度:O(n)

• 建图:需要处理 n-1 条边,时间复杂度为 O(n)。

• DFS遍历:每个节点恰好被访问一次,在每次访问时,处理其所有子节点。虽然每个节点可能有多个子节点,但整棵树的边总数是 n-1,因此所有节点的子节点处理次数总和是 O(n)。DFS的整体时间复杂度为 O(n)。

• 综上,算法的总时间复杂度为 O(n)。

空间复杂度:O(n)

• 邻接表存储:需要存储 n 个节点的邻接关系,空间复杂度为 O(n)。

• 递归调用栈:在最坏情况下(树退化为一条链),递归深度为 n,空间复杂度为 O(n)。

• 综上,算法的总空间复杂度为 O(n)。

Go完整代码如下:

package main

import (

"fmt"

)

func minIncrease(n int, edges [][]int, cost []int) (ans int) {

g := make([][]int, n)

for _, e := range edges {

x, y := e[0], e[1]

g[x] = append(g[x], y)

g[y] = append(g[y], x)

}

g[0] = append(g[0], -1)

var dfs func(int, int)int

dfs = func(x, fa int) (maxS int) {

cnt := 0

for _, y := range g[x] {

if y == fa {

continue

}

mx := dfs(y, x)

if mx > maxS {

maxS = mx

cnt = 1

} elseif mx == maxS {

cnt++

}

}

ans += len(g[x]) - 1 - cnt

return maxS + cost[x]

}

dfs(0, -1)

return

}

func main {

n := 3

edges := [][]int{{0, 1}, {0, 2}}

cost := []int{2, 1, 3}

result := minIncrease(n, edges, cost)

fmt.Println(result)

}

Python完整代码如下:

# -*-coding:utf-8-*-

from typing import List

def minIncrease(n: int, edges: List[List[int]], cost: List[int]) -> int:

g = [[] for _ in range(n)]

for x, y in edges:

g[x].append(y)

g[y].append(x)

g[0].append(-1) # 添加虚拟父节点,方便处理根节点

ans = 0

def dfs(x: int, fa: int) -> int:

nonlocal ans

maxS = 0

cnt = 0

for y in g[x]:

if y == fa:

continue

mx = dfs(y, x)

if mx > maxS:

maxS = mx

cnt = 1

elif mx == maxS:

cnt += 1

ans += len(g[x]) - 1 - cnt

return maxS + cost[x]

dfs(0, -1)

return ans

if __name__ == "__main__":

n = 3

edges = [[0, 1], [0, 2]]

cost = [2, 1, 3]

result = minIncrease(n, edges, cost)

print(result)

C++完整代码如下:

#include

#include

#include

using namespace std;

int minIncrease(int n, vector>& edges, vector& cost) {

vector> g(n);

// 构建邻接表

for (auto& e : edges) {

int x = e[0], y = e[1];

g[x].push_back(y);

g[y].push_back(x);

}

g[0].push_back(-1); // 添加虚拟父节点,方便处理根节点

int ans = 0;

// 使用 function 包装递归函数

function dfs = [&](int x, int fa) -> int {

int maxS = 0;

int cnt = 0;

for (int y : g[x]) {

if (y == fa) continue;

int mx = dfs(y, x);

if (mx > maxS) {

maxS = mx;

cnt = 1;

} elseif (mx == maxS) {

cnt++;

}

}

ans += (int)g[x].size - 1 - cnt;

return maxS + cost[x];

};

dfs(0, -1);

return ans;

}

int main {

int n = 3;

vector> edges = {{0, 1}, {0, 2}};

vector cost = {2, 1, 3};

int result = minIncrease(n, edges, cost);

cout

return0;

}

我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。

欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。