Skip to content

Commit 57da030

Browse files
authored
feat: add solutions to lc problems: No.0337,0338 (doocs#1643)
* No.0337.House Robber III * No.0338.Counting Bits
1 parent ad401d9 commit 57da030

File tree

13 files changed

+437
-276
lines changed

13 files changed

+437
-276
lines changed

solution/0300-0399/0337.House Robber III/README.md

+79-70
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,22 @@
4848

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

51-
记忆化搜索。
51+
**方法一:树形 DP**
52+
53+
我们定义一个函数 $dfs(root)$,表示偷取以 $root$ 为根的二叉树的最大金额。该函数返回一个二元组 $(a, b)$,其中 $a$ 表示偷取 $root$ 节点时能得到的最大金额,而 $b$ 表示不偷取 $root$ 节点时能得到的最大金额。
54+
55+
函数 $dfs(root)$ 的计算过程如下:
56+
57+
如果 $root$ 为空,那么显然有 $dfs(root) = (0, 0)$。
58+
59+
否则,我们首先计算出左右子节点的结果,即 $dfs(root.left)$ 和 $dfs(root.right)$,这样就得到了两对值 $(l_a, l_b)$ 以及 $(r_a, r_b)$。对于 $dfs(root)$ 的结果,我们可以分为两种情况:
60+
61+
- 如果偷取 $root$ 节点,那么不能偷取其左右子节点,结果为 $root.val + l_b + r_b$;
62+
- 如果不偷取 $root$ 节点,那么可以偷取其左右子节点,结果为 $\max(l_a, l_b) + \max(r_a, r_b)$。
63+
64+
在主函数中,我们可以直接返回 $dfs(root)$ 的较大值,即 $\max(dfs(root))$。
65+
66+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点数。
5267

5368
<!-- tabs:start -->
5469

@@ -64,22 +79,15 @@
6479
# self.left = left
6580
# self.right = right
6681
class Solution:
67-
def rob(self, root: TreeNode) -> int:
68-
@cache
69-
def dfs(root):
82+
def rob(self, root: Optional[TreeNode]) -> int:
83+
def dfs(root: Optional[TreeNode]) -> (int, int):
7084
if root is None:
71-
return 0
72-
if root.left is None and root.right is None:
73-
return root.val
74-
a = dfs(root.left) + dfs(root.right)
75-
b = root.val
76-
if root.left:
77-
b += dfs(root.left.left) + dfs(root.left.right)
78-
if root.right:
79-
b += dfs(root.right.left) + dfs(root.right.right)
80-
return max(a, b)
81-
82-
return dfs(root)
85+
return 0, 0
86+
la, lb = dfs(root.left)
87+
ra, rb = dfs(root.right)
88+
return root.val + lb + rb, max(la, lb) + max(ra, rb)
89+
90+
return max(dfs(root))
8391
```
8492

8593
### **Java**
@@ -103,31 +111,18 @@ class Solution:
103111
* }
104112
*/
105113
class Solution {
106-
private Map<TreeNode, Integer> memo;
107-
108114
public int rob(TreeNode root) {
109-
memo = new HashMap<>();
110-
return dfs(root);
115+
int[] ans = dfs(root);
116+
return Math.max(ans[0], ans[1]);
111117
}
112118

113-
private int dfs(TreeNode root) {
119+
private int[] dfs(TreeNode root) {
114120
if (root == null) {
115-
return 0;
116-
}
117-
if (memo.containsKey(root)) {
118-
return memo.get(root);
119-
}
120-
int a = dfs(root.left) + dfs(root.right);
121-
int b = root.val;
122-
if (root.left != null) {
123-
b += dfs(root.left.left) + dfs(root.left.right);
124-
}
125-
if (root.right != null) {
126-
b += dfs(root.right.left) + dfs(root.right.right);
121+
return new int[2];
127122
}
128-
int res = Math.max(a, b);
129-
memo.put(root, res);
130-
return res;
123+
int[] l = dfs(root.left);
124+
int[] r = dfs(root.right);
125+
return new int[] {root.val + l[1] + r[1], Math.max(l[0], l[1]) + Math.max(r[0], r[1])};
131126
}
132127
}
133128
```
@@ -148,22 +143,17 @@ class Solution {
148143
*/
149144
class Solution {
150145
public:
151-
unordered_map<TreeNode*, int> memo;
152-
153146
int rob(TreeNode* root) {
154-
return dfs(root);
155-
}
156-
157-
int dfs(TreeNode* root) {
158-
if (!root) return 0;
159-
if (memo.count(root)) return memo[root];
160-
int a = dfs(root->left) + dfs(root->right);
161-
int b = root->val;
162-
if (root->left) b += dfs(root->left->left) + dfs(root->left->right);
163-
if (root->right) b += dfs(root->right->left) + dfs(root->right->right);
164-
int res = max(a, b);
165-
memo[root] = res;
166-
return res;
147+
function<pair<int, int>(TreeNode*)> dfs = [&](TreeNode* root) -> pair<int, int> {
148+
if (!root) {
149+
return make_pair(0, 0);
150+
}
151+
auto [la, lb] = dfs(root->left);
152+
auto [ra, rb] = dfs(root->right);
153+
return make_pair(root->val + lb + rb, max(la, lb) + max(ra, rb));
154+
};
155+
auto [a, b] = dfs(root);
156+
return max(a, b);
167157
}
168158
};
169159
```
@@ -180,28 +170,17 @@ public:
180170
* }
181171
*/
182172
func rob(root *TreeNode) int {
183-
memo := make(map[*TreeNode]int)
184-
var dfs func(root *TreeNode) int
185-
dfs = func(root *TreeNode) int {
173+
var dfs func(*TreeNode) (int, int)
174+
dfs = func(root *TreeNode) (int, int) {
186175
if root == nil {
187-
return 0
176+
return 0, 0
188177
}
189-
if _, ok := memo[root]; ok {
190-
return memo[root]
191-
}
192-
a := dfs(root.Left) + dfs(root.Right)
193-
b := root.Val
194-
if root.Left != nil {
195-
b += dfs(root.Left.Left) + dfs(root.Left.Right)
196-
}
197-
if root.Right != nil {
198-
b += dfs(root.Right.Left) + dfs(root.Right.Right)
199-
}
200-
res := max(a, b)
201-
memo[root] = res
202-
return res
178+
la, lb := dfs(root.Left)
179+
ra, rb := dfs(root.Right)
180+
return root.Val + lb + rb, max(la, lb) + max(ra, rb)
203181
}
204-
return dfs(root)
182+
a, b := dfs(root)
183+
return max(a, b)
205184
}
206185
207186
func max(a, b int) int {
@@ -212,6 +191,36 @@ func max(a, b int) int {
212191
}
213192
```
214193

194+
### **TypeScript**
195+
196+
```ts
197+
/**
198+
* Definition for a binary tree node.
199+
* class TreeNode {
200+
* val: number
201+
* left: TreeNode | null
202+
* right: TreeNode | null
203+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
204+
* this.val = (val===undefined ? 0 : val)
205+
* this.left = (left===undefined ? null : left)
206+
* this.right = (right===undefined ? null : right)
207+
* }
208+
* }
209+
*/
210+
211+
function rob(root: TreeNode | null): number {
212+
const dfs = (root: TreeNode | null): [number, number] => {
213+
if (!root) {
214+
return [0, 0];
215+
}
216+
const [la, lb] = dfs(root.left);
217+
const [ra, rb] = dfs(root.right);
218+
return [root.val + lb + rb, Math.max(la, lb) + Math.max(ra, rb)];
219+
};
220+
return Math.max(...dfs(root));
221+
}
222+
```
223+
215224
### **...**
216225

217226
```

solution/0300-0399/0337.House Robber III/README_EN.md

+63-69
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,15 @@
4949
# self.left = left
5050
# self.right = right
5151
class Solution:
52-
def rob(self, root: TreeNode) -> int:
53-
@cache
54-
def dfs(root):
52+
def rob(self, root: Optional[TreeNode]) -> int:
53+
def dfs(root: Optional[TreeNode]) -> (int, int):
5554
if root is None:
56-
return 0
57-
if root.left is None and root.right is None:
58-
return root.val
59-
a = dfs(root.left) + dfs(root.right)
60-
b = root.val
61-
if root.left:
62-
b += dfs(root.left.left) + dfs(root.left.right)
63-
if root.right:
64-
b += dfs(root.right.left) + dfs(root.right.right)
65-
return max(a, b)
66-
67-
return dfs(root)
55+
return 0, 0
56+
la, lb = dfs(root.left)
57+
ra, rb = dfs(root.right)
58+
return root.val + lb + rb, max(la, lb) + max(ra, rb)
59+
60+
return max(dfs(root))
6861
```
6962

7063
### **Java**
@@ -86,31 +79,18 @@ class Solution:
8679
* }
8780
*/
8881
class Solution {
89-
private Map<TreeNode, Integer> memo;
90-
9182
public int rob(TreeNode root) {
92-
memo = new HashMap<>();
93-
return dfs(root);
83+
int[] ans = dfs(root);
84+
return Math.max(ans[0], ans[1]);
9485
}
9586

96-
private int dfs(TreeNode root) {
87+
private int[] dfs(TreeNode root) {
9788
if (root == null) {
98-
return 0;
99-
}
100-
if (memo.containsKey(root)) {
101-
return memo.get(root);
89+
return new int[2];
10290
}
103-
int a = dfs(root.left) + dfs(root.right);
104-
int b = root.val;
105-
if (root.left != null) {
106-
b += dfs(root.left.left) + dfs(root.left.right);
107-
}
108-
if (root.right != null) {
109-
b += dfs(root.right.left) + dfs(root.right.right);
110-
}
111-
int res = Math.max(a, b);
112-
memo.put(root, res);
113-
return res;
91+
int[] l = dfs(root.left);
92+
int[] r = dfs(root.right);
93+
return new int[] {root.val + l[1] + r[1], Math.max(l[0], l[1]) + Math.max(r[0], r[1])};
11494
}
11595
}
11696
```
@@ -131,22 +111,17 @@ class Solution {
131111
*/
132112
class Solution {
133113
public:
134-
unordered_map<TreeNode*, int> memo;
135-
136114
int rob(TreeNode* root) {
137-
return dfs(root);
138-
}
139-
140-
int dfs(TreeNode* root) {
141-
if (!root) return 0;
142-
if (memo.count(root)) return memo[root];
143-
int a = dfs(root->left) + dfs(root->right);
144-
int b = root->val;
145-
if (root->left) b += dfs(root->left->left) + dfs(root->left->right);
146-
if (root->right) b += dfs(root->right->left) + dfs(root->right->right);
147-
int res = max(a, b);
148-
memo[root] = res;
149-
return res;
115+
function<pair<int, int>(TreeNode*)> dfs = [&](TreeNode* root) -> pair<int, int> {
116+
if (!root) {
117+
return make_pair(0, 0);
118+
}
119+
auto [la, lb] = dfs(root->left);
120+
auto [ra, rb] = dfs(root->right);
121+
return make_pair(root->val + lb + rb, max(la, lb) + max(ra, rb));
122+
};
123+
auto [a, b] = dfs(root);
124+
return max(a, b);
150125
}
151126
};
152127
```
@@ -163,28 +138,17 @@ public:
163138
* }
164139
*/
165140
func rob(root *TreeNode) int {
166-
memo := make(map[*TreeNode]int)
167-
var dfs func(root *TreeNode) int
168-
dfs = func(root *TreeNode) int {
141+
var dfs func(*TreeNode) (int, int)
142+
dfs = func(root *TreeNode) (int, int) {
169143
if root == nil {
170-
return 0
171-
}
172-
if _, ok := memo[root]; ok {
173-
return memo[root]
174-
}
175-
a := dfs(root.Left) + dfs(root.Right)
176-
b := root.Val
177-
if root.Left != nil {
178-
b += dfs(root.Left.Left) + dfs(root.Left.Right)
179-
}
180-
if root.Right != nil {
181-
b += dfs(root.Right.Left) + dfs(root.Right.Right)
144+
return 0, 0
182145
}
183-
res := max(a, b)
184-
memo[root] = res
185-
return res
146+
la, lb := dfs(root.Left)
147+
ra, rb := dfs(root.Right)
148+
return root.Val + lb + rb, max(la, lb) + max(ra, rb)
186149
}
187-
return dfs(root)
150+
a, b := dfs(root)
151+
return max(a, b)
188152
}
189153
190154
func max(a, b int) int {
@@ -195,6 +159,36 @@ func max(a, b int) int {
195159
}
196160
```
197161

162+
### **TypeScript**
163+
164+
```ts
165+
/**
166+
* Definition for a binary tree node.
167+
* class TreeNode {
168+
* val: number
169+
* left: TreeNode | null
170+
* right: TreeNode | null
171+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
172+
* this.val = (val===undefined ? 0 : val)
173+
* this.left = (left===undefined ? null : left)
174+
* this.right = (right===undefined ? null : right)
175+
* }
176+
* }
177+
*/
178+
179+
function rob(root: TreeNode | null): number {
180+
const dfs = (root: TreeNode | null): [number, number] => {
181+
if (!root) {
182+
return [0, 0];
183+
}
184+
const [la, lb] = dfs(root.left);
185+
const [ra, rb] = dfs(root.right);
186+
return [root.val + lb + rb, Math.max(la, lb) + Math.max(ra, rb)];
187+
};
188+
return Math.max(...dfs(root));
189+
}
190+
```
191+
198192
### **...**
199193

200194
```

0 commit comments

Comments
 (0)