Skip to content

Commit 3de8be6

Browse files
committed
feat: add solutions to lcp problem: No.64
1 parent 9fcd034 commit 3de8be6

File tree

5 files changed

+353
-0
lines changed

5 files changed

+353
-0
lines changed

lcp/LCP 64. 二叉树灯饰/README.md

+196
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,218 @@
4747

4848
<!-- 这里可写通用的实现逻辑 -->
4949

50+
**方法一:递归**
51+
52+
我们注意到,三个开关只能影响当前节点及其左右子节点,因此我们可以将当前节点的状态分为四种:
53+
54+
- 全灭:当前节点及其左右子节点的灯均处于关闭状态;
55+
- 全亮:当前节点及其左右子节点的灯均处于开启状态;
56+
- 当前灯亮:当前节点的灯处于开启状态,其余节点的灯均处于关闭状态;
57+
- 当前灯灭:当前节点的灯处于关闭状态,其余节点的灯均处于开启状态;
58+
59+
我们用 $t_1$, $t_2$, $t_3$, $t_4$ 分别表示四种状态下,需要操作的开关次数。我们可以发现,对于当前节点的状态,我们先递归计算其左右子节点的状态 $l_1$, $l_2$, $l_3$, $l_4$ 和 $r_1$, $r_2$, $r_3$, $r_4$,然后根据当前节点的灯的状态,可以得到四种状态下的最小操作次数:
60+
61+
如果当前节点的灯处于开启状态,那么:
62+
63+
- 全灭 $t_1 = min(l_1 + r_1 + 1, l_2 + r_2 + 1, l_3 + r_3 + 1, l_4 + r_4 + 3)$
64+
- 全亮 $t_2 = min(l_1 + r_1 + 2, l_2 + r_2, l_3 + r_3 + 2, l_4 + r_4 + 2)$
65+
- 当前灯亮 $t_3 = min(l_1 + r_1, l_2 + r_2 + 2, l_3 + r_3 + 2, l_4 + r_4 + 2)$
66+
- 当前灯灭 $t_4 = min(l_1 + r_1 + 1, l_2 + r_2 + 1, l_3 + r_3 + 3, l_4 + r_4 + 1)$
67+
68+
如果当前节点的灯处于关闭状态,那么:
69+
70+
- 全灭 $t_1 = min(l_1 + r_1, l_2 + r_2 + 2, l_3 + r_3 + 2, l_4 + r_4 + 2)$
71+
- 全亮 $t_2 = min(l_1 + r_1 + 1, l_2 + r_2 + 1, l_3 + r_3 + 3, l_4 + r_4 + 1)$
72+
- 当前灯亮 $t_3 = min(l_1 + r_1 + 1, l_2 + r_2 + 1, l_3 + r_3 + 1, l_4 + r_4 + 3)$
73+
- 当前灯灭 $t_4 = min(l_1 + r_1 + 2, l_2 + r_2, l_3 + r_3 + 2, l_4 + r_4 + 2)$
74+
75+
最后,我们返回四种状态下的最小操作次数即可。
76+
77+
最终答案为 $t_1$,因为我们需要将所有节点的灯都关闭。
78+
79+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为二叉树的节点个数。
80+
5081
<!-- tabs:start -->
5182

5283
### **Python3**
5384

5485
<!-- 这里可写当前语言的特殊实现逻辑 -->
5586

5687
```python
88+
# Definition for a binary tree node.
89+
# class TreeNode:
90+
# def __init__(self, x):
91+
# self.val = x
92+
# self.left = None
93+
# self.right = None
94+
class Solution:
95+
def closeLampInTree(self, root: TreeNode) -> int:
96+
def dfs(root):
97+
if root is None:
98+
return 0, 0, 0, 0
99+
l1, l2, l3, l4 = dfs(root.left)
100+
r1, r2, r3, r4 = dfs(root.right)
101+
t1 = t2 = t3 = t4 = inf
102+
if root.val:
103+
t1 = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3)
104+
t2 = min(l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2)
105+
t3 = min(l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2)
106+
t4 = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1)
107+
else:
108+
t1 = min(l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2)
109+
t2 = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1)
110+
t3 = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3)
111+
t4 = min(l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2)
112+
return t1, t2, t3, t4
57113

114+
return dfs(root)[0]
58115
```
59116

60117
### **Java**
61118

62119
<!-- 这里可写当前语言的特殊实现逻辑 -->
63120

64121
```java
122+
/**
123+
* Definition for a binary tree node.
124+
* public class TreeNode {
125+
* int val;
126+
* TreeNode left;
127+
* TreeNode right;
128+
* TreeNode(int x) { val = x; }
129+
* }
130+
*/
131+
class Solution {
132+
public int closeLampInTree(TreeNode root) {
133+
return dfs(root)[0];
134+
}
135+
136+
private int[] dfs(TreeNode root) {
137+
int[] ans = new int[4];
138+
if (root == null) {
139+
return ans;
140+
}
141+
int[] left = dfs(root.left);
142+
int[] right = dfs(root.right);
143+
int l1 = left[0], l2 = left[1], l3 = left[2], l4 = left[3];
144+
int r1 = right[0], r2 = right[1], r3 = right[2], r4 = right[3];
145+
if (root.val != 0) {
146+
ans[0] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3);
147+
ans[1] = min(l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2);
148+
ans[2] = min(l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2);
149+
ans[3] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1);
150+
} else {
151+
ans[0] = min(l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2);
152+
ans[1] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1);
153+
ans[2] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3);
154+
ans[3] = min(l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2);
155+
}
156+
return ans;
157+
}
158+
159+
private int min(int... nums) {
160+
int ans = 1 << 30;
161+
for (int num : nums) {
162+
ans = Math.min(ans, num);
163+
}
164+
return ans;
165+
}
166+
}
167+
```
168+
169+
### **C++**
170+
171+
```cpp
172+
/**
173+
* Definition for a binary tree node.
174+
* struct TreeNode {
175+
* int val;
176+
* TreeNode *left;
177+
* TreeNode *right;
178+
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
179+
* };
180+
*/
181+
class Solution {
182+
public:
183+
int closeLampInTree(TreeNode* root) {
184+
return dfs(root)[0];
185+
}
186+
187+
vector<int> dfs(TreeNode* root) {
188+
vector<int> ans(4);
189+
if (!root) {
190+
return ans;
191+
}
192+
auto left = dfs(root->left);
193+
auto right = dfs(root->right);
194+
int l1 = left[0], l2 = left[1], l3 = left[2], l4 = left[3];
195+
int r1 = right[0], r2 = right[1], r3 = right[2], r4 = right[3];
196+
if (root->val) {
197+
ans[0] = min({l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3});
198+
ans[1] = min({l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2});
199+
ans[2] = min({l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2});
200+
ans[3] = min({l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1});
201+
} else {
202+
ans[0] = min({l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2});
203+
ans[1] = min({l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1});
204+
ans[2] = min({l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3});
205+
ans[3] = min({l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2});
206+
}
207+
return ans;
208+
}
209+
};
210+
```
211+
212+
### **Go**
213+
214+
```go
215+
/**
216+
* Definition for a binary tree node.
217+
* type TreeNode struct {
218+
* Val int
219+
* Left *TreeNode
220+
* Right *TreeNode
221+
* }
222+
*/
223+
func closeLampInTree(root *TreeNode) (ans int) {
224+
const inf = 1 << 30
225+
var dfs func(*TreeNode) (int, int, int, int)
226+
dfs = func(root *TreeNode) (int, int, int, int) {
227+
if root == nil {
228+
return 0, 0, 0, 0
229+
}
230+
l1, l2, l3, l4 := dfs(root.Left)
231+
r1, r2, r3, r4 := dfs(root.Right)
232+
t1, t2, t3, t4 := inf, inf, inf, inf
233+
if root.Val == 1 {
234+
t1 = min(l1+r1+1, l2+r2+1, l3+r3+1, l4+r4+3)
235+
t2 = min(l1+r1+2, l2+r2, l3+r3+2, l4+r4+2)
236+
t3 = min(l1+r1, l2+r2+2, l3+r3+2, l4+r4+2)
237+
t4 = min(l1+r1+1, l2+r2+1, l3+r3+3, l4+r4+1)
238+
} else {
239+
t1 = min(l1+r1, l2+r2+2, l3+r3+2, l4+r4+2)
240+
t2 = min(l1+r1+1, l2+r2+1, l3+r3+3, l4+r4+1)
241+
t3 = min(l1+r1+1, l2+r2+1, l3+r3+1, l4+r4+3)
242+
t4 = min(l1+r1+2, l2+r2, l3+r3+2, l4+r4+2)
243+
}
244+
return t1, t2, t3, t4
245+
}
246+
ans, _, _, _ = dfs(root)
247+
return
248+
}
65249

250+
func min(a, b, c, d int) int {
251+
if b < a {
252+
a = b
253+
}
254+
if c < a {
255+
a = c
256+
}
257+
if d < a {
258+
a = d
259+
}
260+
return a
261+
}
66262
```
67263

68264
### **...**
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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 closeLampInTree(TreeNode* root) {
13+
return dfs(root)[0];
14+
}
15+
16+
vector<int> dfs(TreeNode* root) {
17+
vector<int> ans(4);
18+
if (!root) {
19+
return ans;
20+
}
21+
auto left = dfs(root->left);
22+
auto right = dfs(root->right);
23+
int l1 = left[0], l2 = left[1], l3 = left[2], l4 = left[3];
24+
int r1 = right[0], r2 = right[1], r3 = right[2], r4 = right[3];
25+
if (root->val) {
26+
ans[0] = min({l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3});
27+
ans[1] = min({l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2});
28+
ans[2] = min({l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2});
29+
ans[3] = min({l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1});
30+
} else {
31+
ans[0] = min({l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2});
32+
ans[1] = min({l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1});
33+
ans[2] = min({l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3});
34+
ans[3] = min({l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2});
35+
}
36+
return ans;
37+
}
38+
};
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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 closeLampInTree(root *TreeNode) (ans int) {
10+
const inf = 1 << 30
11+
var dfs func(*TreeNode) (int, int, int, int)
12+
dfs = func(root *TreeNode) (int, int, int, int) {
13+
if root == nil {
14+
return 0, 0, 0, 0
15+
}
16+
l1, l2, l3, l4 := dfs(root.Left)
17+
r1, r2, r3, r4 := dfs(root.Right)
18+
t1, t2, t3, t4 := inf, inf, inf, inf
19+
if root.Val == 1 {
20+
t1 = min(l1+r1+1, l2+r2+1, l3+r3+1, l4+r4+3)
21+
t2 = min(l1+r1+2, l2+r2, l3+r3+2, l4+r4+2)
22+
t3 = min(l1+r1, l2+r2+2, l3+r3+2, l4+r4+2)
23+
t4 = min(l1+r1+1, l2+r2+1, l3+r3+3, l4+r4+1)
24+
} else {
25+
t1 = min(l1+r1, l2+r2+2, l3+r3+2, l4+r4+2)
26+
t2 = min(l1+r1+1, l2+r2+1, l3+r3+3, l4+r4+1)
27+
t3 = min(l1+r1+1, l2+r2+1, l3+r3+1, l4+r4+3)
28+
t4 = min(l1+r1+2, l2+r2, l3+r3+2, l4+r4+2)
29+
}
30+
return t1, t2, t3, t4
31+
}
32+
ans, _, _, _ = dfs(root)
33+
return
34+
}
35+
36+
func min(a, b, c, d int) int {
37+
if b < a {
38+
a = b
39+
}
40+
if c < a {
41+
a = c
42+
}
43+
if d < a {
44+
a = d
45+
}
46+
return a
47+
}
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* public class TreeNode {
4+
* int val;
5+
* TreeNode left;
6+
* TreeNode right;
7+
* TreeNode(int x) { val = x; }
8+
* }
9+
*/
10+
class Solution {
11+
public int closeLampInTree(TreeNode root) {
12+
return dfs(root)[0];
13+
}
14+
15+
private int[] dfs(TreeNode root) {
16+
int[] ans = new int[4];
17+
if (root == null) {
18+
return ans;
19+
}
20+
int[] left = dfs(root.left);
21+
int[] right = dfs(root.right);
22+
int l1 = left[0], l2 = left[1], l3 = left[2], l4 = left[3];
23+
int r1 = right[0], r2 = right[1], r3 = right[2], r4 = right[3];
24+
if (root.val != 0) {
25+
ans[0] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3);
26+
ans[1] = min(l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2);
27+
ans[2] = min(l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2);
28+
ans[3] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1);
29+
} else {
30+
ans[0] = min(l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2);
31+
ans[1] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1);
32+
ans[2] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3);
33+
ans[3] = min(l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2);
34+
}
35+
return ans;
36+
}
37+
38+
private int min(int... nums) {
39+
int ans = 1 << 30;
40+
for (int num : nums) {
41+
ans = Math.min(ans, num);
42+
}
43+
return ans;
44+
}
45+
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Definition for a binary tree node.
2+
# class TreeNode:
3+
# def __init__(self, x):
4+
# self.val = x
5+
# self.left = None
6+
# self.right = None
7+
class Solution:
8+
def closeLampInTree(self, root: TreeNode) -> int:
9+
def dfs(root):
10+
if root is None:
11+
return 0, 0, 0, 0
12+
l1, l2, l3, l4 = dfs(root.left)
13+
r1, r2, r3, r4 = dfs(root.right)
14+
t1 = t2 = t3 = t4 = inf
15+
if root.val:
16+
t1 = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3)
17+
t2 = min(l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2)
18+
t3 = min(l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2)
19+
t4 = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1)
20+
else:
21+
t1 = min(l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2)
22+
t2 = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1)
23+
t3 = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3)
24+
t4 = min(l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2)
25+
return t1, t2, t3, t4
26+
27+
return dfs(root)[0]

0 commit comments

Comments
 (0)