Skip to content

Commit 9c8672e

Browse files
authored
feat: add solutions to lc problem: No.3068 (doocs#3422)
No.3068.Find the Maximum Sum of Node Values
1 parent f55bdf7 commit 9c8672e

File tree

7 files changed

+209
-70
lines changed

7 files changed

+209
-70
lines changed

solution/3000-3099/3068.Find the Maximum Sum of Node Values/README.md

+81-23
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,28 @@ tags:
9898

9999
<!-- solution:start -->
100100

101-
### 方法一
101+
### 方法一:动态规划
102+
103+
对于任意一个数 $x$,与 $k$ 异或偶数次后,值不变。所以,对于一棵树的任意一条路径,我们将路径上所有的边都进行操作,那么该路径上除了起点和终点外,其他节点的值都不会改变。
104+
105+
另外,无论进行了多少次操作,总会有偶数个元素异或了 $k$,其余元素不变。
106+
107+
因此,问题转化为:对于数组 $\textit{nums}$,任选其中偶数个元素异或 $k$,使得和最大。
108+
109+
我们可以使用动态规划解决这个问题。设 $f_0$ 表示当前有偶数个元素异或了 $k$ 时的最大和,而 $f_1$ 表示当前有奇数个元素异或了 $k$ 时的最大和。那么状态转移方程为:
110+
111+
$$
112+
\begin{aligned}
113+
f_0 &= \max(f_0 + x, f_1 + (x \oplus k)) \\
114+
f_1 &= \max(f_1 + x, f_0 + (x \oplus k))
115+
\end{aligned}
116+
$$
117+
118+
其中 $x$ 表示当前元素的值。
119+
120+
我们遍历数组 $\textit{nums}$,根据上述状态转移方程更新 $f_0$ 和 $f_1$,最后返回 $f_0$ 即可。
121+
122+
时间复杂度 $O(n)$,其中 $n$ 为数组 $\textit{nums}$ 的长度。空间复杂度 $O(1)$。
102123

103124
<!-- tabs:start -->
104125

@@ -135,37 +156,74 @@ class Solution {
135156
class Solution {
136157
public:
137158
long long maximumValueSum(vector<int>& nums, int k, vector<vector<int>>& edges) {
138-
long long totalSum = 0;
139-
int count = 0;
140-
int positiveMin = INT_MAX;
141-
int negativeMax = INT_MIN;
142-
143-
for (int nodeValue : nums) {
144-
int nodeValAfterOperation = nodeValue ^ k;
145-
totalSum += nodeValue;
146-
int netChange = nodeValAfterOperation - nodeValue;
147-
148-
if (netChange > 0) {
149-
positiveMin = min(positiveMin, netChange);
150-
totalSum += netChange;
151-
count += 1;
152-
} else {
153-
negativeMax = max(negativeMax, netChange);
154-
}
155-
}
156-
157-
if (count % 2 == 0) {
158-
return totalSum;
159+
long long f0 = 0, f1 = -0x3f3f3f3f;
160+
for (int x : nums) {
161+
long long tmp = f0;
162+
f0 = max(f0 + x, f1 + (x ^ k));
163+
f1 = max(f1 + x, tmp + (x ^ k));
159164
}
160-
return max(totalSum - positiveMin, totalSum + negativeMax);
165+
return f0;
161166
}
162167
};
163168
```
164169
165170
#### Go
166171
167172
```go
173+
func maximumValueSum(nums []int, k int, edges [][]int) int64 {
174+
f0, f1 := 0, -0x3f3f3f3f
175+
for _, x := range nums {
176+
f0, f1 = max(f0+x, f1+(x^k)), max(f1+x, f0+(x^k))
177+
}
178+
return int64(f0)
179+
}
180+
```
181+
182+
#### TypeScript
183+
184+
```ts
185+
function maximumValueSum(nums: number[], k: number, edges: number[][]): number {
186+
let [f0, f1] = [0, -Infinity];
187+
for (const x of nums) {
188+
[f0, f1] = [Math.max(f0 + x, f1 + (x ^ k)), Math.max(f1 + x, f0 + (x ^ k))];
189+
}
190+
return f0;
191+
}
192+
```
193+
194+
#### Rust
168195

196+
```rust
197+
impl Solution {
198+
pub fn maximum_value_sum(nums: Vec<i32>, k: i32, edges: Vec<Vec<i32>>) -> i64 {
199+
let mut f0: i64 = 0;
200+
let mut f1: i64 = i64::MIN;
201+
202+
for &x in &nums {
203+
let tmp = f0;
204+
f0 = std::cmp::max(f0 + x as i64, f1 + (x ^ k) as i64);
205+
f1 = std::cmp::max(f1 + x as i64, tmp + (x ^ k) as i64);
206+
}
207+
208+
f0
209+
}
210+
}
211+
```
212+
213+
#### C#
214+
215+
```cs
216+
public class Solution {
217+
public long MaximumValueSum(int[] nums, int k, int[][] edges) {
218+
long f0 = 0, f1 = -0x3f3f3f3f;
219+
foreach (int x in nums) {
220+
long tmp = f0;
221+
f0 = Math.Max(f0 + x, f1 + (x ^ k));
222+
f1 = Math.Max(f1 + x, tmp + (x ^ k));
223+
}
224+
return f0;
225+
}
226+
}
169227
```
170228

171229
<!-- tabs:end -->

solution/3000-3099/3068.Find the Maximum Sum of Node Values/README_EN.md

+83-25
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,28 @@ It can be shown that 9 is the maximum achievable sum of values.
9090

9191
<!-- solution:start -->
9292

93-
### Solution 1
93+
### Solution 1: Dynamic Programming
94+
95+
For any number $x$, its value remains unchanged after being XORed with $k$ an even number of times. Therefore, for any path in a tree, if we perform the operation on all edges in the path, the values of all nodes on the path except the start and end nodes will not change.
96+
97+
Additionally, no matter how many operations are performed, there will always be an even number of elements XORed with $k$, and the remaining elements will remain unchanged.
98+
99+
Thus, the problem is transformed into: for the array $\textit{nums}$, select an even number of elements to XOR with $k$ to maximize the sum.
100+
101+
We can use dynamic programming to solve this problem. Let $f_0$ represent the maximum sum when an even number of elements have been XORed with $k$, and $f_1$ represent the maximum sum when an odd number of elements have been XORed with $k$. The state transition equations are:
102+
103+
$$
104+
\begin{aligned}
105+
f_0 &= \max(f_0 + x, f_1 + (x \oplus k)) \\
106+
f_1 &= \max(f_1 + x, f_0 + (x \oplus k))
107+
\end{aligned}
108+
$$
109+
110+
where $x$ represents the current element's value.
111+
112+
We traverse the array $\textit{nums}$ and update $f_0$ and $f_1$ according to the above state transition equations. Finally, we return $f_0$.
113+
114+
The time complexity is $O(n)$, where $n$ is the length of the array $\textit{nums}$. The space complexity is $O(1)$.
94115

95116
<!-- tabs:start -->
96117

@@ -100,8 +121,8 @@ It can be shown that 9 is the maximum achievable sum of values.
100121
class Solution:
101122
def maximumValueSum(self, nums: List[int], k: int, edges: List[List[int]]) -> int:
102123
f0, f1 = 0, -inf
103-
for v in nums:
104-
f0, f1 = max(f0 + v, f1 + (v ^ k)), max(f1 + v, f0 + (v ^ k))
124+
for x in nums:
125+
f0, f1 = max(f0 + x, f1 + (x ^ k)), max(f1 + x, f0 + (x ^ k))
105126
return f0
106127
```
107128

@@ -127,37 +148,74 @@ class Solution {
127148
class Solution {
128149
public:
129150
long long maximumValueSum(vector<int>& nums, int k, vector<vector<int>>& edges) {
130-
long long totalSum = 0;
131-
int count = 0;
132-
int positiveMin = INT_MAX;
133-
int negativeMax = INT_MIN;
134-
135-
for (int nodeValue : nums) {
136-
int nodeValAfterOperation = nodeValue ^ k;
137-
totalSum += nodeValue;
138-
int netChange = nodeValAfterOperation - nodeValue;
139-
140-
if (netChange > 0) {
141-
positiveMin = min(positiveMin, netChange);
142-
totalSum += netChange;
143-
count += 1;
144-
} else {
145-
negativeMax = max(negativeMax, netChange);
146-
}
147-
}
148-
149-
if (count % 2 == 0) {
150-
return totalSum;
151+
long long f0 = 0, f1 = -0x3f3f3f3f;
152+
for (int x : nums) {
153+
long long tmp = f0;
154+
f0 = max(f0 + x, f1 + (x ^ k));
155+
f1 = max(f1 + x, tmp + (x ^ k));
151156
}
152-
return max(totalSum - positiveMin, totalSum + negativeMax);
157+
return f0;
153158
}
154159
};
155160
```
156161
157162
#### Go
158163
159164
```go
165+
func maximumValueSum(nums []int, k int, edges [][]int) int64 {
166+
f0, f1 := 0, -0x3f3f3f3f
167+
for _, x := range nums {
168+
f0, f1 = max(f0+x, f1+(x^k)), max(f1+x, f0+(x^k))
169+
}
170+
return int64(f0)
171+
}
172+
```
173+
174+
#### TypeScript
175+
176+
```ts
177+
function maximumValueSum(nums: number[], k: number, edges: number[][]): number {
178+
let [f0, f1] = [0, -Infinity];
179+
for (const x of nums) {
180+
[f0, f1] = [Math.max(f0 + x, f1 + (x ^ k)), Math.max(f1 + x, f0 + (x ^ k))];
181+
}
182+
return f0;
183+
}
184+
```
185+
186+
#### Rust
160187

188+
```rust
189+
impl Solution {
190+
pub fn maximum_value_sum(nums: Vec<i32>, k: i32, edges: Vec<Vec<i32>>) -> i64 {
191+
let mut f0: i64 = 0;
192+
let mut f1: i64 = i64::MIN;
193+
194+
for &x in &nums {
195+
let tmp = f0;
196+
f0 = std::cmp::max(f0 + x as i64, f1 + (x ^ k) as i64);
197+
f1 = std::cmp::max(f1 + x as i64, tmp + (x ^ k) as i64);
198+
}
199+
200+
f0
201+
}
202+
}
203+
```
204+
205+
#### C#
206+
207+
```cs
208+
public class Solution {
209+
public long MaximumValueSum(int[] nums, int k, int[][] edges) {
210+
long f0 = 0, f1 = -0x3f3f3f3f;
211+
foreach (int x in nums) {
212+
long tmp = f0;
213+
f0 = Math.Max(f0 + x, f1 + (x ^ k));
214+
f1 = Math.Max(f1 + x, tmp + (x ^ k));
215+
}
216+
return f0;
217+
}
218+
}
161219
```
162220

163221
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,12 @@
11
class Solution {
22
public:
33
long long maximumValueSum(vector<int>& nums, int k, vector<vector<int>>& edges) {
4-
long long totalSum = 0;
5-
int count = 0;
6-
int positiveMin = INT_MAX;
7-
int negativeMax = INT_MIN;
8-
9-
for (int nodeValue : nums) {
10-
int nodeValAfterOperation = nodeValue ^ k;
11-
totalSum += nodeValue;
12-
int netChange = nodeValAfterOperation - nodeValue;
13-
14-
if (netChange > 0) {
15-
positiveMin = min(positiveMin, netChange);
16-
totalSum += netChange;
17-
count += 1;
18-
} else {
19-
negativeMax = max(negativeMax, netChange);
20-
}
4+
long long f0 = 0, f1 = -0x3f3f3f3f;
5+
for (int x : nums) {
6+
long long tmp = f0;
7+
f0 = max(f0 + x, f1 + (x ^ k));
8+
f1 = max(f1 + x, tmp + (x ^ k));
219
}
22-
23-
if (count % 2 == 0) {
24-
return totalSum;
25-
}
26-
return max(totalSum - positiveMin, totalSum + negativeMax);
10+
return f0;
2711
}
2812
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
public class Solution {
2+
public long MaximumValueSum(int[] nums, int k, int[][] edges) {
3+
long f0 = 0, f1 = -0x3f3f3f3f;
4+
foreach (int x in nums) {
5+
long tmp = f0;
6+
f0 = Math.Max(f0 + x, f1 + (x ^ k));
7+
f1 = Math.Max(f1 + x, tmp + (x ^ k));
8+
}
9+
return f0;
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
func maximumValueSum(nums []int, k int, edges [][]int) int64 {
2+
f0, f1 := 0, -0x3f3f3f3f
3+
for _, x := range nums {
4+
f0, f1 = max(f0+x, f1+(x^k)), max(f1+x, f0+(x^k))
5+
}
6+
return int64(f0)
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
impl Solution {
2+
pub fn maximum_value_sum(nums: Vec<i32>, k: i32, edges: Vec<Vec<i32>>) -> i64 {
3+
let mut f0: i64 = 0;
4+
let mut f1: i64 = i64::MIN;
5+
6+
for &x in &nums {
7+
let tmp = f0;
8+
f0 = std::cmp::max(f0 + x as i64, f1 + (x ^ k) as i64);
9+
f1 = std::cmp::max(f1 + x as i64, tmp + (x ^ k) as i64);
10+
}
11+
12+
f0
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function maximumValueSum(nums: number[], k: number, edges: number[][]): number {
2+
let [f0, f1] = [0, -Infinity];
3+
for (const x of nums) {
4+
[f0, f1] = [Math.max(f0 + x, f1 + (x ^ k)), Math.max(f1 + x, f0 + (x ^ k))];
5+
}
6+
return f0;
7+
}

0 commit comments

Comments
 (0)