Skip to content

Commit 8948e31

Browse files
committed
feat: add solutions to lcp problem: No.34
1 parent 7e9ef55 commit 8948e31

File tree

6 files changed

+252
-39
lines changed

6 files changed

+252
-39
lines changed

lcp/LCP 34. 二叉树染色/README.md

+139-19
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@
3333

3434
<!-- 这里可写通用的实现逻辑 -->
3535

36+
**方法一:动态规划(树形 DP)**
37+
38+
我们考虑以 $root$ 为根节点的子树,且 $root$ 节点连着 $t$ 个染色节点的最大价值,其中 $t \in [0, k]$。我们用状态 $f[root][t]$ 来表示。
39+
40+
如果我们不染色 $root$ 节点,那么 $root$ 的左右节点可以连着 $t \in [0, k]$ 个染色节点,即 $f[root][0] = \max_{t \in [0, k]} f[root.left][t] + \max_{t \in [0, k]} f[root.right][t]$。
41+
42+
如果我们染色 $root$ 节点,那么 $root$ 的左右节点可以连着最多共 $k-1$ 个染色节点,不妨假设左节点连着 $i$ 个染色节点,右节点连着 $j$ 个染色节点,其中 $i \in [0, k-1]$, $j \in [0, k-1-i]$,那么 $f[root][i + j + 1] = \max_{i \in [0, k-1], j \in [0, k-1-i]} f[root.left][i] + f[root.right][j] + root.val$。
43+
44+
最后答案就是 $f[root][t]$ 中的最大值。
45+
46+
时间复杂度 $O(n \times k^2)$,空间复杂度 $O(n \times k)$。其中 $n$ 和 $k$ 分别是二叉树的节点数和 $k$ 的值。
47+
3648
<!-- tabs:start -->
3749

3850
### **Python3**
@@ -50,17 +62,15 @@
5062

5163
class Solution:
5264
def maxValue(self, root: TreeNode, k: int) -> int:
53-
def dfs(root):
65+
def dfs(root: TreeNode) -> List[int]:
5466
ans = [0] * (k + 1)
5567
if root is None:
5668
return ans
5769
l, r = dfs(root.left), dfs(root.right)
70+
ans[0] = max(l) + max(r)
5871
for i in range(k):
5972
for j in range(k - i):
6073
ans[i + j + 1] = max(ans[i + j + 1], l[i] + r[j] + root.val)
61-
for i in range(k + 1):
62-
for j in range(k + 1):
63-
ans[0] = max(ans[0], l[i] + r[j])
6474
return ans
6575

6676
return max(dfs(root))
@@ -81,37 +91,147 @@ class Solution:
8191
* }
8292
*/
8393
class Solution {
94+
private int k;
95+
8496
public int maxValue(TreeNode root, int k) {
85-
int[] t = dfs(root, k);
86-
int ans = 0;
87-
for (int v : t) {
88-
ans = Math.max(ans, v);
89-
}
90-
return ans;
97+
this.k = k;
98+
return Arrays.stream(dfs(root)).max().getAsInt();
9199
}
92100

93-
private int[] dfs(TreeNode root, int k) {
101+
private int[] dfs(TreeNode root) {
94102
int[] ans = new int[k + 1];
95103
if (root == null) {
96104
return ans;
97105
}
98-
int[] l = dfs(root.left, k);
99-
int[] r = dfs(root.right, k);
106+
int[] l = dfs(root.left);
107+
int[] r = dfs(root.right);
108+
ans[0] = Arrays.stream(l).max().getAsInt() + Arrays.stream(r).max().getAsInt();
100109
for (int i = 0; i < k; ++i) {
101110
for (int j = 0; j < k - i; ++j) {
102-
ans[i + j + 1] = Math.max(ans[i + j + 1], l[i] + r[j] + root.val);
103-
}
104-
}
105-
for (int i = 0; i <= k; ++i) {
106-
for (int j = 0; j <= k; ++j) {
107-
ans[0] = Math.max(ans[0], l[i] + r[j]);
111+
ans[i + j + 1] = Math.max(ans[i + j + 1], root.val + l[i] + r[j]);
108112
}
109113
}
110114
return ans;
111115
}
112116
}
113117
```
114118

119+
### **C++**
120+
121+
```cpp
122+
/**
123+
* Definition for a binary tree node.
124+
* struct TreeNode {
125+
* int val;
126+
* TreeNode *left;
127+
* TreeNode *right;
128+
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
129+
* };
130+
*/
131+
class Solution {
132+
public:
133+
int maxValue(TreeNode* root, int k) {
134+
function<vector<int>(TreeNode*)> dfs = [&](TreeNode* root) -> vector<int> {
135+
vector<int> ans(k + 1);
136+
if (!root) {
137+
return ans;
138+
}
139+
vector<int> l = dfs(root->left);
140+
vector<int> r = dfs(root->right);
141+
ans[0] = *max_element(l.begin(), l.end()) + *max_element(r.begin(), r.end());
142+
for (int i = 0; i < k; ++i) {
143+
for (int j = 0; j < k - i; ++j) {
144+
ans[i + j + 1] = max(ans[i + j + 1], l[i] + r[j] + root->val);
145+
}
146+
}
147+
return ans;
148+
};
149+
vector<int> ans = dfs(root);
150+
return *max_element(ans.begin(), ans.end());
151+
}
152+
};
153+
```
154+
155+
### **Go**
156+
157+
```go
158+
/**
159+
* Definition for a binary tree node.
160+
* type TreeNode struct {
161+
* Val int
162+
* Left *TreeNode
163+
* Right *TreeNode
164+
* }
165+
*/
166+
func maxValue(root *TreeNode, k int) int {
167+
var dfs func(*TreeNode) []int
168+
dfs = func(node *TreeNode) []int {
169+
ans := make([]int, k+1)
170+
if node == nil {
171+
return ans
172+
}
173+
l := dfs(node.Left)
174+
r := dfs(node.Right)
175+
ans[0] = max(l...) + max(r...)
176+
for i := 0; i < k; i++ {
177+
for j := 0; j < k-i; j++ {
178+
ans[i+j+1] = max(ans[i+j+1], l[i]+r[j]+node.Val)
179+
}
180+
}
181+
return ans
182+
}
183+
return max(dfs(root)...)
184+
}
185+
186+
func max(nums ...int) int {
187+
ans := nums[0]
188+
for _, x := range nums {
189+
if x > ans {
190+
ans = x
191+
}
192+
}
193+
return ans
194+
}
195+
```
196+
197+
### **JavaScript**
198+
199+
```js
200+
/**
201+
* Definition for a binary tree node.
202+
* function TreeNode(val) {
203+
* this.val = val;
204+
* this.left = this.right = null;
205+
* }
206+
*/
207+
/**
208+
* @param {TreeNode} root
209+
* @param {number} k
210+
* @return {number}
211+
*/
212+
var maxValue = function (root, k) {
213+
const dfs = root => {
214+
const ans = Array(k + 1).fill(0);
215+
if (!root) {
216+
return ans;
217+
}
218+
const l = dfs(root.left);
219+
const r = dfs(root.right);
220+
ans[0] = Math.max(...l) + Math.max(...r);
221+
for (let i = 0; i < k; i++) {
222+
for (let j = 0; j < k - i; ++j) {
223+
ans[i + j + 1] = Math.max(
224+
ans[i + j + 1],
225+
l[i] + r[j] + root.val,
226+
);
227+
}
228+
}
229+
return ans;
230+
};
231+
return Math.max(...dfs(root));
232+
};
233+
```
234+
115235
### **...**
116236

117237
```
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* struct TreeNode {
4+
* int val;
5+
* TreeNode *left;
6+
* TreeNode *right;
7+
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
8+
* };
9+
*/
10+
class Solution {
11+
public:
12+
int maxValue(TreeNode* root, int k) {
13+
function<vector<int>(TreeNode*)> dfs = [&](TreeNode* root) -> vector<int> {
14+
vector<int> ans(k + 1);
15+
if (!root) {
16+
return ans;
17+
}
18+
vector<int> l = dfs(root->left);
19+
vector<int> r = dfs(root->right);
20+
ans[0] = *max_element(l.begin(), l.end()) + *max_element(r.begin(), r.end());
21+
for (int i = 0; i < k; ++i) {
22+
for (int j = 0; j < k - i; ++j) {
23+
ans[i + j + 1] = max(ans[i + j + 1], l[i] + r[j] + root->val);
24+
}
25+
}
26+
return ans;
27+
};
28+
vector<int> ans = dfs(root);
29+
return *max_element(ans.begin(), ans.end());
30+
}
31+
};
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* type TreeNode struct {
4+
* Val int
5+
* Left *TreeNode
6+
* Right *TreeNode
7+
* }
8+
*/
9+
func maxValue(root *TreeNode, k int) int {
10+
var dfs func(*TreeNode) []int
11+
dfs = func(node *TreeNode) []int {
12+
ans := make([]int, k+1)
13+
if node == nil {
14+
return ans
15+
}
16+
l := dfs(node.Left)
17+
r := dfs(node.Right)
18+
ans[0] = max(l...) + max(r...)
19+
for i := 0; i < k; i++ {
20+
for j := 0; j < k-i; j++ {
21+
ans[i+j+1] = max(ans[i+j+1], l[i]+r[j]+node.Val)
22+
}
23+
}
24+
return ans
25+
}
26+
return max(dfs(root)...)
27+
}
28+
29+
func max(nums ...int) int {
30+
ans := nums[0]
31+
for _, x := range nums {
32+
if x > ans {
33+
ans = x
34+
}
35+
}
36+
return ans
37+
}

lcp/LCP 34. 二叉树染色/Solution.java

+10-16
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,26 @@
88
* }
99
*/
1010
class Solution {
11+
private int k;
12+
1113
public int maxValue(TreeNode root, int k) {
12-
int[] t = dfs(root, k);
13-
int ans = 0;
14-
for (int v : t) {
15-
ans = Math.max(ans, v);
16-
}
17-
return ans;
14+
this.k = k;
15+
return Arrays.stream(dfs(root)).max().getAsInt();
1816
}
1917

20-
private int[] dfs(TreeNode root, int k) {
18+
private int[] dfs(TreeNode root) {
2119
int[] ans = new int[k + 1];
2220
if (root == null) {
2321
return ans;
2422
}
25-
int[] l = dfs(root.left, k);
26-
int[] r = dfs(root.right, k);
23+
int[] l = dfs(root.left);
24+
int[] r = dfs(root.right);
25+
ans[0] = Arrays.stream(l).max().getAsInt() + Arrays.stream(r).max().getAsInt();
2726
for (int i = 0; i < k; ++i) {
2827
for (int j = 0; j < k - i; ++j) {
29-
ans[i + j + 1] = Math.max(ans[i + j + 1], l[i] + r[j] + root.val);
30-
}
31-
}
32-
for (int i = 0; i <= k; ++i) {
33-
for (int j = 0; j <= k; ++j) {
34-
ans[0] = Math.max(ans[0], l[i] + r[j]);
28+
ans[i + j + 1] = Math.max(ans[i + j + 1], root.val + l[i] + r[j]);
3529
}
3630
}
3731
return ans;
3832
}
39-
}
33+
}
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* function TreeNode(val) {
4+
* this.val = val;
5+
* this.left = this.right = null;
6+
* }
7+
*/
8+
/**
9+
* @param {TreeNode} root
10+
* @param {number} k
11+
* @return {number}
12+
*/
13+
var maxValue = function (root, k) {
14+
const dfs = root => {
15+
const ans = Array(k + 1).fill(0);
16+
if (!root) {
17+
return ans;
18+
}
19+
const l = dfs(root.left);
20+
const r = dfs(root.right);
21+
ans[0] = Math.max(...l) + Math.max(...r);
22+
for (let i = 0; i < k; i++) {
23+
for (let j = 0; j < k - i; ++j) {
24+
ans[i + j + 1] = Math.max(
25+
ans[i + j + 1],
26+
l[i] + r[j] + root.val,
27+
);
28+
}
29+
}
30+
return ans;
31+
};
32+
return Math.max(...dfs(root));
33+
};

lcp/LCP 34. 二叉树染色/Solution.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,15 @@
88

99
class Solution:
1010
def maxValue(self, root: TreeNode, k: int) -> int:
11-
def dfs(root):
11+
def dfs(root: TreeNode) -> List[int]:
1212
ans = [0] * (k + 1)
1313
if root is None:
1414
return ans
1515
l, r = dfs(root.left), dfs(root.right)
16+
ans[0] = max(l) + max(r)
1617
for i in range(k):
1718
for j in range(k - i):
1819
ans[i + j + 1] = max(ans[i + j + 1], l[i] + r[j] + root.val)
19-
for i in range(k + 1):
20-
for j in range(k + 1):
21-
ans[0] = max(ans[0], l[i] + r[j])
2220
return ans
2321

2422
return max(dfs(root))

0 commit comments

Comments
 (0)