Skip to content

Commit 7c6b88c

Browse files
committedJun 19, 2023
feat: add solutions to lc problem: No.0198
No.0198.House Robber
1 parent fed16e8 commit 7c6b88c

File tree

8 files changed

+157
-360
lines changed

8 files changed

+157
-360
lines changed
 

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

+65-166
Original file line numberDiff line numberDiff line change
@@ -42,123 +42,86 @@
4242

4343
<!-- 这里可写通用的实现逻辑 -->
4444

45-
**方法一:记忆化搜索**
45+
**方法一:动态规划**
4646

47-
我们设计函数 $dfs(i)$ 表示从第 $i$ 间房屋开始偷窃,能偷窃到的最高金额。答案为 $dfs(0)$。
47+
我们定义 $f[i]$ 表示前 $i$ 间房屋能偷窃到的最高总金额,初始时 $f[0]=0$, $f[1]=nums[0]$。
4848

49-
对于第 $i$ 间房屋,有偷窃和不偷窃两种选择。如果偷窃,那么下一间房屋就不能偷窃,偷窃总金额为当前房屋金额加上下下间房屋开始的偷窃最高金额,即 $nums[i] + dfs(i + 2)$。如果不偷窃,那么下一间房屋就可以偷窃,偷窃总金额为下一间房屋开始的偷窃最高金额,即 $dfs(i + 1)$。两种选择取最大值作为函数 $dfs(i)$ 的返回值。
49+
考虑 $i \gt 1$ 的情况,第 $i$ 间房屋有两个选项:
5050

51-
我们可以使用记忆化搜索,避免重复计算。
51+
- 不偷窃第 $i$ 间房屋,偷窃总金额为 $f[i-1]$;
52+
- 偷窃第 $i$ 间房屋,偷窃总金额为 $f[i-2]+nums[i-1]$;
5253

53-
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为房屋数量。
54+
因此,我们可以得到状态转移方程:
5455

55-
**方法二:动态规划**
56+
$$
57+
f[i]=
58+
\begin{cases}
59+
0, & i=0 \\
60+
nums[0], & i=1 \\
61+
\max(f[i-1],f[i-2]+nums[i-1]), & i \gt 1
62+
\end{cases}
63+
$$
5664

57-
我们也可以将记忆化搜索改成动态规划
65+
最终的答案即为 $f[n]$,其中 $n$ 是数组的长度
5866

59-
定义 $dp[i]$ 表示偷窃前 $i$ 个房屋能得到的最高金额。答案为 $dp[n]$
67+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组长度
6068

61-
状态转移方程为 $dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1])$。
62-
63-
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为房屋数量。
64-
65-
**方法三:动态规划(空间优化)**
66-
67-
注意到方法二中的状态转移方程只和 $dp[i - 1]$ 和 $dp[i - 2]$ 有关,因此我们可以只用两个变量来维护这两个状态,从而将空间复杂度优化到 $O(1)$。
68-
69-
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为房屋数量。
69+
注意到当 $i \gt 2$ 时,$f[i]$ 只和 $f[i-1]$ 与 $f[i-2]$ 有关,因此我们可以使用两个变量代替数组,将空间复杂度降到 $O(1)$。
7070

7171
<!-- tabs:start -->
7272

7373
### **Python3**
7474

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

77-
```python
78-
class Solution:
79-
def rob(self, nums: List[int]) -> int:
80-
@cache
81-
def dfs(i):
82-
if i >= len(nums):
83-
return 0
84-
return max(nums[i] + dfs(i + 2), dfs(i + 1))
85-
86-
return dfs(0)
87-
```
88-
8977
```python
9078
class Solution:
9179
def rob(self, nums: List[int]) -> int:
9280
n = len(nums)
93-
dp = [0] * (n + 1)
94-
dp[1] = nums[0]
81+
f = [0] * (n + 1)
82+
f[1] = nums[0]
9583
for i in range(2, n + 1):
96-
dp[i] = max(nums[i - 1] + dp[i - 2], dp[i - 1])
97-
return dp[n]
84+
f[i] = max(f[i - 1], f[i - 2] + nums[i - 1])
85+
return f[n]
9886
```
9987

10088
```python
10189
class Solution:
10290
def rob(self, nums: List[int]) -> int:
103-
a, b = 0, nums[0]
104-
for num in nums[1:]:
105-
a, b = b, max(num + a, b)
106-
return b
91+
f, g = 0, nums[0]
92+
for x in nums[1:]:
93+
f, g = g, max(f + x, g)
94+
return g
10795
```
10896

10997
### **Java**
11098

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

113-
```java
114-
class Solution {
115-
private int[] f;
116-
private int[] nums;
117-
118-
public int rob(int[] nums) {
119-
this.nums = nums;
120-
f = new int[nums.length];
121-
Arrays.fill(f, -1);
122-
return dfs(0);
123-
}
124-
125-
private int dfs(int i) {
126-
if (i >= nums.length) {
127-
return 0;
128-
}
129-
if (f[i] != -1) {
130-
return f[i];
131-
}
132-
f[i] = Math.max(nums[i] + dfs(i + 2), dfs(i + 1));
133-
return f[i];
134-
}
135-
}
136-
```
137-
138101
```java
139102
class Solution {
140103
public int rob(int[] nums) {
141104
int n = nums.length;
142-
int[] dp = new int[n + 1];
143-
dp[1] = nums[0];
105+
int[] f = new int[n + 1];
106+
f[1] = nums[0];
144107
for (int i = 2; i <= n; ++i) {
145-
dp[i] = Math.max(nums[i - 1] + dp[i - 2], dp[i - 1]);
108+
f[i] = Math.max(f[i - 1], f[i - 2] + nums[i - 1]);
146109
}
147-
return dp[n];
110+
return f[n];
148111
}
149112
}
150113
```
151114

152115
```java
153116
class Solution {
154117
public int rob(int[] nums) {
155-
int a = 0, b = nums[0];
118+
int f = 0, g = nums[0];
156119
for (int i = 1; i < nums.length; ++i) {
157-
int c = Math.max(nums[i] + a, b);
158-
a = b;
159-
b = c;
120+
int t = g;
121+
g = Math.max(g, f + nums[i]);
122+
f = t;
160123
}
161-
return b;
124+
return g;
162125
}
163126
}
164127
```
@@ -170,29 +133,13 @@ class Solution {
170133
public:
171134
int rob(vector<int>& nums) {
172135
int n = nums.size();
173-
vector<int> f(n, -1);
174-
function<int(int)> dfs = [&](int i) -> int {
175-
if (i >= n) return 0;
176-
if (f[i] != -1) return f[i];
177-
f[i] = max(nums[i] + dfs(i + 2), dfs(i + 1));
178-
return f[i];
179-
};
180-
return dfs(0);
181-
}
182-
};
183-
```
184-
185-
```cpp
186-
class Solution {
187-
public:
188-
int rob(vector<int>& nums) {
189-
int n = nums.size();
190-
vector<int> dp(n + 1);
191-
dp[1] = nums[0];
136+
int f[n + 1];
137+
memset(f, 0, sizeof(f));
138+
f[1] = nums[0];
192139
for (int i = 2; i <= n; ++i) {
193-
dp[i] = max(nums[i - 1] + dp[i - 2], dp[i - 1]);
140+
f[i] = max(f[i - 1], f[i - 2] + nums[i - 1]);
194141
}
195-
return dp[n];
142+
return f[n];
196143
}
197144
};
198145
```
@@ -201,14 +148,13 @@ public:
201148
class Solution {
202149
public:
203150
int rob(vector<int>& nums) {
204-
int n = nums.size();
205-
int a = 0, b = nums[0];
206-
for (int i = 1; i < n; ++i) {
207-
int c = max(nums[i] + a, b);
208-
a = b;
209-
b = c;
151+
int f = 0, g = nums[0];
152+
for (int i = 1; i < nums.size(); ++i) {
153+
int t = g;
154+
g = max(g, f + nums[i]);
155+
f = t;
210156
}
211-
return b;
157+
return g;
212158
}
213159
};
214160
```
@@ -218,41 +164,12 @@ public:
218164
```go
219165
func rob(nums []int) int {
220166
n := len(nums)
221-
f := make([]int, n)
222-
for i := range f {
223-
f[i] = -1
224-
}
225-
var dfs func(int) int
226-
dfs = func(i int) int {
227-
if i >= n {
228-
return 0
229-
}
230-
if f[i] != -1 {
231-
return f[i]
232-
}
233-
f[i] = max(nums[i]+dfs(i+2), dfs(i+1))
234-
return f[i]
235-
}
236-
return dfs(0)
237-
}
238-
239-
func max(a, b int) int {
240-
if a > b {
241-
return a
242-
}
243-
return b
244-
}
245-
```
246-
247-
```go
248-
func rob(nums []int) int {
249-
n := len(nums)
250-
dp := make([]int, n+1)
251-
dp[1] = nums[0]
167+
f := make([]int, n+1)
168+
f[1] = nums[0]
252169
for i := 2; i <= n; i++ {
253-
dp[i] = max(nums[i-1]+dp[i-2], dp[i-1])
170+
f[i] = max(f[i-1], f[i-2]+nums[i-1])
254171
}
255-
return dp[n]
172+
return f[n]
256173
}
257174

258175
func max(a, b int) int {
@@ -265,11 +182,11 @@ func max(a, b int) int {
265182

266183
```go
267184
func rob(nums []int) int {
268-
a, b, n := 0, nums[0], len(nums)
269-
for i := 1; i < n; i++ {
270-
a, b = b, max(nums[i]+a, b)
185+
f, g := 0, nums[0]
186+
for _, x := range nums[1:] {
187+
f, g = g, max(f+x, g)
271188
}
272-
return b
189+
return g
273190
}
274191

275192
func max(a, b int) int {
@@ -285,40 +202,22 @@ func max(a, b int) int {
285202
```ts
286203
function rob(nums: number[]): number {
287204
const n = nums.length;
288-
const f = new Array(n).fill(-1);
289-
function dfs(i) {
290-
if (i >= n) {
291-
return 0;
292-
}
293-
if (f[i] != -1) {
294-
return f[i];
295-
}
296-
f[i] = Math.max(nums[i] + dfs(i + 2), dfs(i + 1));
297-
return f[i];
298-
}
299-
return dfs(0);
300-
}
301-
```
302-
303-
```ts
304-
function rob(nums: number[]): number {
305-
const n = nums.length;
306-
const dp = new Array(n + 1).fill(0);
307-
dp[1] = nums[0];
205+
const f: number[] = Array(n + 1).fill(0);
206+
f[1] = nums[0];
308207
for (let i = 2; i <= n; ++i) {
309-
dp[i] = Math.max(nums[i - 1] + dp[i - 2], dp[i - 1]);
208+
f[i] = Math.max(f[i - 1], f[i - 2] + nums[i - 1]);
310209
}
311-
return dp[n];
210+
return f[n];
312211
}
313212
```
314213

315214
```ts
316215
function rob(nums: number[]): number {
317-
const dp = [0, 0];
318-
for (const num of nums) {
319-
[dp[0], dp[1]] = [dp[1], Math.max(dp[1], dp[0] + num)];
216+
let [f, g] = [0, nums[0]];
217+
for (let i = 1; i < nums.length; ++i) {
218+
[f, g] = [g, Math.max(f + nums[i], g)];
320219
}
321-
return dp[1];
220+
return g;
322221
}
323222
```
324223

@@ -327,11 +226,11 @@ function rob(nums: number[]): number {
327226
```rust
328227
impl Solution {
329228
pub fn rob(nums: Vec<i32>) -> i32 {
330-
let mut dp = [0, 0];
331-
for num in nums {
332-
dp = [dp[1], dp[1].max(dp[0] + num)]
229+
let mut f = [0, 0];
230+
for x in nums {
231+
f = [f[1], f[1].max(f[0] + x)]
333232
}
334-
dp[1]
233+
f[1]
335234
}
336235
}
337236
```

0 commit comments

Comments
 (0)