Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4b80b47

Browse files
rain84yanglbme
andauthored
feat: add solutions to lc problem: No.0198 (doocs#3249)
Co-authored-by: Libin YANG <contact@yanglibin.info>
1 parent b1c2f99 commit 4b80b47

23 files changed

+631
-76
lines changed

‎solution/0100-0199/0198.House Robber/README.md‎

Lines changed: 215 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,174 @@ tags:
5555

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

58-
### 方法一:动态规划
58+
### 方法一:记忆化搜索
59+
60+
我们设计一个函数 $\textit{dfs}(i),ドル表示从第 $i$ 间房屋开始偷窃能够得到的最高金额。那么答案即为 $\textit{dfs}(0)$。
61+
62+
函数 $\textit{dfs}(i)$ 的执行过程如下:
63+
64+
- 如果 $i \ge \textit{len}(\textit{nums}),ドル表示所有房屋都被考虑过了,直接返回 0ドル$;
65+
- 否则,考虑偷窃第 $i$ 间房屋,那么 $\textit{dfs}(i) = \textit{nums}[i] + \textit{dfs}(i+2)$;不偷窃第 $i$ 间房屋,那么 $\textit{dfs}(i) = \textit{dfs}(i+1)$。
66+
- 返回 $\max(\textit{nums}[i] + \textit{dfs}(i+2), \textit{dfs}(i+1))$。
67+
68+
为了避免重复计算,我们使用记忆化搜索的方法,将 $\textit{dfs}(i)$ 的结果保存在一个数组或哈希表中,每次计算前先查询是否已经计算过,如果计算过直接返回结果。
69+
70+
时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 是数组长度。
71+
72+
<!-- tabs:start -->
73+
74+
#### Python3
75+
76+
```python
77+
class Solution:
78+
def rob(self, nums: List[int]) -> int:
79+
@cache
80+
def dfs(i: int) -> int:
81+
if i >= len(nums):
82+
return 0
83+
return max(nums[i] + dfs(i + 2), dfs(i + 1))
84+
85+
return dfs(0)
86+
```
87+
88+
#### Java
89+
90+
```java
91+
class Solution {
92+
private Integer[] f;
93+
private int[] nums;
94+
95+
public int rob(int[] nums) {
96+
this.nums = nums;
97+
f = new Integer[nums.length];
98+
return dfs(0);
99+
}
100+
101+
private int dfs(int i) {
102+
if (i >= nums.length) {
103+
return 0;
104+
}
105+
if (f[i] == null) {
106+
f[i] = Math.max(nums[i] + dfs(i + 2), dfs(i + 1));
107+
}
108+
return f[i];
109+
}
110+
}
111+
```
112+
113+
#### C++
114+
115+
```cpp
116+
class Solution {
117+
public:
118+
int rob(vector<int>& nums) {
119+
int n = nums.size();
120+
int f[n];
121+
memset(f, -1, sizeof(f));
122+
auto dfs = [&](auto&& dfs, int i) -> int {
123+
if (i >= n) {
124+
return 0;
125+
}
126+
if (f[i] < 0) {
127+
f[i] = max(nums[i] + dfs(dfs, i + 2), dfs(dfs, i + 1));
128+
}
129+
return f[i];
130+
};
131+
return dfs(dfs, 0);
132+
}
133+
};
134+
```
135+
136+
#### Go
137+
138+
```go
139+
func rob(nums []int) int {
140+
n := len(nums)
141+
f := make([]int, n)
142+
for i := range f {
143+
f[i] = -1
144+
}
145+
var dfs func(int) int
146+
dfs = func(i int) int {
147+
if i >= n {
148+
return 0
149+
}
150+
if f[i] < 0 {
151+
f[i] = max(nums[i]+dfs(i+2), dfs(i+1))
152+
}
153+
return f[i]
154+
}
155+
return dfs(0)
156+
}
157+
```
158+
159+
#### TypeScript
160+
161+
```ts
162+
function rob(nums: number[]): number {
163+
const n = nums.length;
164+
const f: number[] = Array(n).fill(-1);
165+
const dfs = (i: number): number => {
166+
if (i >= n) {
167+
return 0;
168+
}
169+
if (f[i] < 0) {
170+
f[i] = Math.max(nums[i] + dfs(i + 2), dfs(i + 1));
171+
}
172+
return f[i];
173+
};
174+
return dfs(0);
175+
}
176+
```
177+
178+
#### Rust
179+
180+
```rust
181+
impl Solution {
182+
pub fn rob(nums: Vec<i32>) -> i32 {
183+
fn dfs(i: usize, nums: &Vec<i32>, f: &mut Vec<i32>) -> i32 {
184+
if i >= nums.len() {
185+
return 0;
186+
}
187+
if f[i] < 0 {
188+
f[i] = (nums[i] + dfs(i + 2, nums, f)).max(dfs(i + 1, nums, f));
189+
}
190+
f[i]
191+
}
192+
193+
let n = nums.len();
194+
let mut f = vec![-1; n];
195+
dfs(0, &nums, &mut f)
196+
}
197+
}
198+
```
199+
200+
#### JavaScript
201+
202+
```js
203+
function rob(nums) {
204+
const n = nums.length;
205+
const f = Array(n).fill(-1);
206+
const dfs = i => {
207+
if (i >= n) {
208+
return 0;
209+
}
210+
if (f[i] < 0) {
211+
f[i] = Math.max(nums[i] + dfs(i + 2), dfs(i + 1));
212+
}
213+
return f[i];
214+
};
215+
return dfs(0);
216+
}
217+
```
218+
219+
<!-- tabs:end -->
220+
221+
<!-- solution:end -->
222+
223+
<!-- solution:start -->
224+
225+
### 方法二:动态规划
59226

60227
我们定义 $f[i]$ 表示前 $i$ 间房屋能偷窃到的最高总金额,初始时 $f[0]=0,ドル $f[1]=nums[0]$。
61228

@@ -161,12 +328,28 @@ function rob(nums: number[]): number {
161328
```rust
162329
impl Solution {
163330
pub fn rob(nums: Vec<i32>) -> i32 {
164-
let mut f = [0, 0];
165-
for x in nums {
166-
f = [f[0].max(f[1]), f[0] + x];
331+
let n = nums.len();
332+
let mut f = vec![0; n + 1];
333+
f[1] = nums[0];
334+
for i in 2..=n {
335+
f[i] = f[i - 1].max(f[i - 2] + nums[i - 1]);
167336
}
168-
f[0].max(f[1])
337+
f[n]
338+
}
339+
}
340+
```
341+
342+
#### JavaScript
343+
344+
```js
345+
function rob(nums) {
346+
const n = nums.length;
347+
const f = Array(n + 1).fill(0);
348+
f[1] = nums[0];
349+
for (let i = 2; i <= n; ++i) {
350+
f[i] = Math.max(f[i - 1], f[i - 2] + nums[i - 1]);
169351
}
352+
return f[n];
170353
}
171354
```
172355

@@ -176,7 +359,7 @@ impl Solution {
176359

177360
<!-- solution:start -->
178361

179-
### 方法二:动态规划(空间优化)
362+
### 方法三:动态规划(空间优化)
180363

181364
我们注意到,当 $i \gt 2$ 时,$f[i]$ 只和 $f[i-1]$ 与 $f[i-2]$ 有关,因此我们可以使用两个变量代替数组,将空间复杂度降到 $O(1)$。
182365

@@ -250,6 +433,32 @@ function rob(nums: number[]): number {
250433
}
251434
```
252435

436+
#### Rust
437+
438+
```rust
439+
impl Solution {
440+
pub fn rob(nums: Vec<i32>) -> i32 {
441+
let mut f = [0, 0];
442+
for x in nums {
443+
f = [f[0].max(f[1]), f[0] + x];
444+
}
445+
f[0].max(f[1])
446+
}
447+
}
448+
```
449+
450+
#### JavaScript
451+
452+
```js
453+
function rob(nums) {
454+
let [f, g] = [0, 0];
455+
for (const x of nums) {
456+
[f, g] = [Math.max(f, g), f + x];
457+
}
458+
return Math.max(f, g);
459+
}
460+
```
461+
253462
<!-- tabs:end -->
254463

255464
<!-- solution:end -->

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /