LeetCode 题解工作台

最大节点价值之和

给你一棵 n 个节点的 无向 树,节点从 0 到 n - 1 编号。树以长度为 n - 1 下标从 0 开始的二维整数数组 edges 的形式给你,其中 edges[i] = [u i , v i ] 表示树中节点 u i 和 v i 之间有一条边。同时给你一个 正 整数 k 和一个长度为 n 下标…

category

6

题型

code_blocks

7

代码语言

hub

3

相关题

当前训练重点

困难 · 二分·树·traversal

bolt

答案摘要

对于任意一个数 ,与 异或偶数次后,值不变。所以,对于一棵树的任意一条路径,我们将路径上所有的边都进行操作,那么该路径上除了起点和终点外,其他节点的值都不会改变。 另外,无论进行了多少次操作,总会有偶数个元素异或了 ,其余元素不变。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 二分·树·traversal 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你一棵 n 个节点的 无向 树,节点从 0 到 n - 1 编号。树以长度为 n - 1 下标从 0 开始的二维整数数组 edges 的形式给你,其中 edges[i] = [ui, vi] 表示树中节点 ui 和 vi 之间有一条边。同时给你一个  整数 k 和一个长度为 n 下标从 0 开始的 非负 整数数组 nums ,其中 nums[i] 表示节点 i 的 价值 。

Alice 想 最大化 树中所有节点价值之和。为了实现这一目标,Alice 可以执行以下操作 任意 次(包括 0 次):

  • 选择连接节点 u 和 v 的边 [u, v] ,并将它们的值更新为:
    • nums[u] = nums[u] XOR k
    • nums[v] = nums[v] XOR k

请你返回 Alice 通过执行以上操作 任意次 后,可以得到所有节点 价值之和 的 最大值 。

 

示例 1:

输入:nums = [1,2,1], k = 3, edges = [[0,1],[0,2]]
输出:6
解释:Alice 可以通过一次操作得到最大价值和 6 :
- 选择边 [0,2] 。nums[0] 和 nums[2] 都变为:1 XOR 3 = 2 ,数组 nums 变为:[1,2,1] -> [2,2,2] 。
所有节点价值之和为 2 + 2 + 2 = 6 。
6 是可以得到最大的价值之和。

示例 2:

输入:nums = [2,3], k = 7, edges = [[0,1]]
输出:9
解释:Alice 可以通过一次操作得到最大和 9 :
- 选择边 [0,1] 。nums[0] 变为:2 XOR 7 = 5 ,nums[1] 变为:3 XOR 7 = 4 ,数组 nums 变为:[2,3] -> [5,4] 。
所有节点价值之和为 5 + 4 = 9 。
9 是可以得到最大的价值之和。

示例 3:

输入:nums = [7,7,7,7,7,7], k = 3, edges = [[0,1],[0,2],[0,3],[0,4],[0,5]]
输出:42
解释:Alice 不需要执行任何操作,就可以得到最大价值之和 42 。

 

提示:

  • 2 <= n == nums.length <= 2 * 104
  • 1 <= k <= 109
  • 0 <= nums[i] <= 109
  • edges.length == n - 1
  • edges[i].length == 2
  • 0 <= edges[i][0], edges[i][1] <= n - 1
  • 输入保证 edges 构成一棵合法的树。
lightbulb

解题思路

方法一:动态规划

对于任意一个数 xx,与 kk 异或偶数次后,值不变。所以,对于一棵树的任意一条路径,我们将路径上所有的边都进行操作,那么该路径上除了起点和终点外,其他节点的值都不会改变。

另外,无论进行了多少次操作,总会有偶数个元素异或了 kk,其余元素不变。

因此,问题转化为:对于数组 nums\textit{nums},任选其中偶数个元素异或 kk,使得和最大。

我们可以使用动态规划解决这个问题。设 f0f_0 表示当前有偶数个元素异或了 kk 时的最大和,而 f1f_1 表示当前有奇数个元素异或了 kk 时的最大和。那么状态转移方程为:

f0=max(f0+x,f1+(xk))f1=max(f1+x,f0+(xk))\begin{aligned} f_0 &= \max(f_0 + x, f_1 + (x \oplus k)) \\ f_1 &= \max(f_1 + x, f_0 + (x \oplus k)) \end{aligned}

其中 xx 表示当前元素的值。

我们遍历数组 nums\textit{nums},根据上述状态转移方程更新 f0f_0f1f_1,最后返回 f0f_0 即可。

时间复杂度 O(n)O(n),其中 nn 为数组 nums\textit{nums} 的长度。空间复杂度 O(1)O(1)

1
2
3
4
5
6
7
class Solution:
    def maximumValueSum(self, nums: List[int], k: int, edges: List[List[int]]) -> int:
        f0, f1 = 0, -inf
        for x in nums:
            f0, f1 = max(f0 + x, f1 + (x ^ k)), max(f1 + x, f0 + (x ^ k))
        return f0
speed

复杂度分析

指标
时间O(n)
空间O(1)
psychology

面试官常问的追问

外企场景
  • question_mark

    They want you to notice that edge operations do not require tree DP over children; the tree only enforces even toggle parity.

  • question_mark

    A strong solution quickly rewrites the problem from modifying edges to selecting node-wise XOR gains under an even-count constraint.

  • question_mark

    If you mention rooting the tree, the useful conclusion is feasibility of any even-sized toggled set, not a full binary-tree recurrence.

warning

常见陷阱

外企场景
  • error

    Greedily taking every node where nums[i] XOR k is larger than nums[i] without checking whether that chosen count is odd.

  • error

    Building a full traversal-based DP on the tree and overcomplicating a problem whose final state depends only on parity of toggled nodes.

  • error

    Assuming the exact edge sequence matters for the maximum sum, when only the reachable even-cardinality set of changed nodes matters.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Return the actual set of nodes to toggle instead of only the maximum sum, which requires reconstructing the parity choice.

  • arrow_right_alt

    Replace the tree with a general connected graph; the same even-parity reachability idea still drives the optimization.

  • arrow_right_alt

    Ask for the maximum sum after exactly m operations, which changes the simple parity view into a tighter operation-count constraint.

help

常见问题

外企场景

最大节点价值之和题解:二分·树·traversal | LeetCode #3068 困难