Skip to content

Commit 06fc7e9

Browse files
authored
Update README_EN.md
1 parent f39078c commit 06fc7e9

File tree

1 file changed

+198
-81
lines changed

1 file changed

+198
-81
lines changed

solution/0100-0199/0198.House Robber/README_EN.md

Lines changed: 198 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,174 @@ Total amount you can rob = 2 + 9 + 1 = 12.
5454

5555
<!-- solution:start -->
5656

57-
### Solution 1: Dynamic Programming
57+
### Solution 1: Memoization Search
58+
59+
We design a function $\textit{dfs}(i)$, which represents the maximum amount of money that can be stolen starting from the $i$-th house. Thus, the answer is $\textit{dfs}(0)$.
60+
61+
The execution process of the function $\textit{dfs}(i)$ is as follows:
62+
63+
- If $i \ge \textit{len}(\textit{nums})$, it means all houses have been considered, and we directly return $0$;
64+
- Otherwise, consider stealing from the $i$-th house, then $\textit{dfs}(i) = \textit{nums}[i] + \textit{dfs}(i+2)$; if not stealing from the $i$-th house, then $\textit{dfs}(i) = \textit{dfs}(i+1)$.
65+
- Return $\max(\textit{nums}[i] + \textit{dfs}(i+2), \textit{dfs}(i+1))$.
66+
67+
To avoid repeated calculations, we use memoization search. The result of $\textit{dfs}(i)$ is saved in an array or hash table. Before each calculation, we first check if it has been calculated. If so, we directly return the result.
68+
69+
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array.
70+
71+
<!-- tabs:start -->
72+
73+
#### Python3
74+
75+
```python
76+
class Solution:
77+
def rob(self, nums: List[int]) -> int:
78+
@cache
79+
def dfs(i: int) -> int:
80+
if i >= len(nums):
81+
return 0
82+
return max(nums[i] + dfs(i + 2), dfs(i + 1))
83+
84+
return dfs(0)
85+
```
86+
87+
#### Java
88+
89+
```java
90+
class Solution {
91+
private Integer[] f;
92+
private int[] nums;
93+
94+
public int rob(int[] nums) {
95+
this.nums = nums;
96+
f = new Integer[nums.length];
97+
return dfs(0);
98+
}
99+
100+
private int dfs(int i) {
101+
if (i >= nums.length) {
102+
return 0;
103+
}
104+
if (f[i] == null) {
105+
f[i] = Math.max(nums[i] + dfs(i + 2), dfs(i + 1));
106+
}
107+
return f[i];
108+
}
109+
}
110+
```
111+
112+
#### C++
113+
114+
```cpp
115+
class Solution {
116+
public:
117+
int rob(vector<int>& nums) {
118+
int n = nums.size();
119+
int f[n];
120+
memset(f, -1, sizeof(f));
121+
auto dfs = [&](auto&& dfs, int i) -> int {
122+
if (i >= n) {
123+
return 0;
124+
}
125+
if (f[i] < 0) {
126+
f[i] = max(nums[i] + dfs(dfs, i + 2), dfs(dfs, i + 1));
127+
}
128+
return f[i];
129+
};
130+
return dfs(dfs, 0);
131+
}
132+
};
133+
```
134+
135+
#### Go
136+
137+
```go
138+
func rob(nums []int) int {
139+
n := len(nums)
140+
f := make([]int, n)
141+
for i := range f {
142+
f[i] = -1
143+
}
144+
var dfs func(int) int
145+
dfs = func(i int) int {
146+
if i >= n {
147+
return 0
148+
}
149+
if f[i] < 0 {
150+
f[i] = max(nums[i]+dfs(i+2), dfs(i+1))
151+
}
152+
return f[i]
153+
}
154+
return dfs(0)
155+
}
156+
```
157+
158+
#### TypeScript
159+
160+
```ts
161+
function rob(nums: number[]): number {
162+
const n = nums.length;
163+
const f: number[] = Array(n).fill(-1);
164+
const dfs = (i: number): number => {
165+
if (i >= n) {
166+
return 0;
167+
}
168+
if (f[i] < 0) {
169+
f[i] = Math.max(nums[i] + dfs(i + 2), dfs(i + 1));
170+
}
171+
return f[i];
172+
};
173+
return dfs(0);
174+
}
175+
```
176+
177+
#### Rust
178+
179+
```rust
180+
impl Solution {
181+
pub fn rob(nums: Vec<i32>) -> i32 {
182+
fn dfs(i: usize, nums: &Vec<i32>, f: &mut Vec<i32>) -> i32 {
183+
if i >= nums.len() {
184+
return 0;
185+
}
186+
if f[i] < 0 {
187+
f[i] = (nums[i] + dfs(i + 2, nums, f)).max(dfs(i + 1, nums, f));
188+
}
189+
f[i]
190+
}
191+
192+
let n = nums.len();
193+
let mut f = vec![-1; n];
194+
dfs(0, &nums, &mut f)
195+
}
196+
}
197+
```
198+
199+
#### JavaScript
200+
201+
```js
202+
function rob(nums) {
203+
const n = nums.length;
204+
const f = Array(n).fill(-1);
205+
const dfs = i => {
206+
if (i >= n) {
207+
return 0;
208+
}
209+
if (f[i] < 0) {
210+
f[i] = Math.max(nums[i] + dfs(i + 2), dfs(i + 1));
211+
}
212+
return f[i];
213+
};
214+
return dfs(0);
215+
}
216+
```
217+
218+
<!-- tabs:end -->
219+
220+
<!-- solution:end -->
221+
222+
<!-- solution:start -->
223+
224+
### Solution 2: Dynamic Programming
58225

59226
We define $f[i]$ as the maximum total amount that can be robbed from the first $i$ houses, initially $f[0]=0$, $f[1]=nums[0]$.
60227

@@ -155,6 +322,22 @@ function rob(nums: number[]): number {
155322
}
156323
```
157324

325+
#### Rust
326+
327+
```rust
328+
impl Solution {
329+
pub fn rob(nums: Vec<i32>) -> i32 {
330+
let n = nums.len();
331+
let mut f = vec![0; n + 1];
332+
f[1] = nums[0];
333+
for i in 2..=n {
334+
f[i] = f[i - 1].max(f[i - 2] + nums[i - 1]);
335+
}
336+
f[n]
337+
}
338+
}
339+
```
340+
158341
#### JavaScript
159342

160343
```js
@@ -169,27 +352,13 @@ function rob(nums) {
169352
}
170353
```
171354

172-
#### Rust
173-
174-
```rust
175-
impl Solution {
176-
pub fn rob(nums: Vec<i32>) -> i32 {
177-
let mut f = [0, 0];
178-
for x in nums {
179-
f = [f[0].max(f[1]), f[0] + x];
180-
}
181-
f[0].max(f[1])
182-
}
183-
}
184-
```
185-
186355
<!-- tabs:end -->
187356

188357
<!-- solution:end -->
189358

190359
<!-- solution:start -->
191360

192-
### Solution 2: Dynamic Programming (Space Optimization)
361+
### Solution 3: Dynamic Programming (Space Optimization)
193362

194363
We notice that when $i \gt 2$, $f[i]$ is only related to $f[i-1]$ and $f[i-2]$. Therefore, we can use two variables instead of an array to reduce the space complexity to $O(1)$.
195364

@@ -263,81 +432,29 @@ function rob(nums: number[]): number {
263432
}
264433
```
265434

266-
#### JavaScript
267-
268-
```js
269-
function rob(nums) {
270-
let [f, g] = [0, 0];
271-
for (const x of nums) {
272-
[f, g] = [Math.max(f, g), f + x];
273-
}
274-
return Math.max(f, g);
275-
}
276-
```
277-
278-
<!-- tabs:end -->
279-
280-
<!-- solution:end -->
281-
282-
<!-- solution:start -->
283-
284-
### Solution 3: Dynamic Programming, top-down approach
285-
286-
<!-- tabs:start -->
287-
288-
#### TypeScript
289-
290-
```ts
291-
export function rob(nums: number[]): number {
292-
const cache: Record<number, number> = {};
293-
const n = nums.length;
294-
let ans = 0;
295-
296-
const dp = (i: number) => {
297-
if (cache[i] !== undefined) return cache[i];
435+
#### Rust
298436

299-
let max = 0;
300-
for (let j = i + 2; j < n; j++) {
301-
max = Math.max(max, dp(j));
437+
```rust
438+
impl Solution {
439+
pub fn rob(nums: Vec<i32>) -> i32 {
440+
let mut f = [0, 0];
441+
for x in nums {
442+
f = [f[0].max(f[1]), f[0] + x];
302443
}
303-
cache[i] = max + nums[i];
304-
305-
return cache[i];
306-
};
307-
308-
for (let i = 0; i < n; i++) {
309-
ans = Math.max(ans, dp(i));
444+
f[0].max(f[1])
310445
}
311-
312-
return ans;
313446
}
314447
```
315448

316449
#### JavaScript
317450

318451
```js
319-
export function rob(nums) {
320-
const cache = {};
321-
const n = nums.length;
322-
let ans = 0;
323-
324-
const dp = i => {
325-
if (cache[i] !== undefined) return cache[i];
326-
327-
let max = 0;
328-
for (let j = i + 2; j < n; j++) {
329-
max = Math.max(max, dp(j));
330-
}
331-
cache[i] = max + nums[i];
332-
333-
return cache[i];
334-
};
335-
336-
for (let i = 0; i < n; i++) {
337-
ans = Math.max(ans, dp(i));
452+
function rob(nums) {
453+
let [f, g] = [0, 0];
454+
for (const x of nums) {
455+
[f, g] = [Math.max(f, g), f + x];
338456
}
339-
340-
return ans;
457+
return Math.max(f, g);
341458
}
342459
```
343460

0 commit comments

Comments
 (0)