Skip to content

Commit 498dcb2

Browse files
committed
feat: add solutions to lc problem: No.0198
No.0198.House Robber
1 parent 40a0d2f commit 498dcb2

File tree

5 files changed

+440
-11
lines changed

5 files changed

+440
-11
lines changed

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

+197-1
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,61 @@
4242

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

45-
动态规划法。状态转移方程:`f(n) = Math.max(f(n - 2) + nums[n], nums[n - 1])`
45+
**方法一:记忆化搜索**
46+
47+
我们设计函数 $dfs(i)$ 表示从第 $i$ 间房屋开始偷窃,能偷窃到的最高金额。答案为 $dfs(0)$。
48+
49+
对于第 $i$ 间房屋,有偷窃和不偷窃两种选择。如果偷窃,那么下一间房屋就不能偷窃,偷窃总金额为当前房屋金额加上下下间房屋开始的偷窃最高金额,即 $nums[i] + dfs(i + 2)$。如果不偷窃,那么下一间房屋就可以偷窃,偷窃总金额为下一间房屋开始的偷窃最高金额,即 $dfs(i + 1)$。两种选择取最大值作为函数 $dfs(i)$ 的返回值。
50+
51+
我们可以使用记忆化搜索,避免重复计算。
52+
53+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为房屋数量。
54+
55+
**方法二:动态规划**
56+
57+
我们也可以将记忆化搜索改成动态规划。
58+
59+
定义 $dp[i]$ 表示偷窃前 $i$ 个房屋能得到的最高金额。答案为 $dp[n]$。
60+
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$ 为房屋数量。
4670

4771
<!-- tabs:start -->
4872

4973
### **Python3**
5074

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

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+
89+
```python
90+
class Solution:
91+
def rob(self, nums: List[int]) -> int:
92+
n = len(nums)
93+
dp = [0] * (n + 1)
94+
dp[1] = nums[0]
95+
for i in range(2, n + 1):
96+
dp[i] = max(nums[i - 1] + dp[i - 2], dp[i - 1])
97+
return dp[n]
98+
```
99+
53100
```python
54101
class Solution:
55102
def rob(self, nums: List[int]) -> int:
@@ -63,6 +110,45 @@ class Solution:
63110

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

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+
138+
```java
139+
class Solution {
140+
public int rob(int[] nums) {
141+
int n = nums.length;
142+
int[] dp = new int[n + 1];
143+
dp[1] = nums[0];
144+
for (int i = 2; i <= n; ++i) {
145+
dp[i] = Math.max(nums[i - 1] + dp[i - 2], dp[i - 1]);
146+
}
147+
return dp[n];
148+
}
149+
}
150+
```
151+
66152
```java
67153
class Solution {
68154
public int rob(int[] nums) {
@@ -79,6 +165,38 @@ class Solution {
79165

80166
### **C++**
81167

168+
```cpp
169+
class Solution {
170+
public:
171+
int rob(vector<int>& nums) {
172+
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];
192+
for (int i = 2; i <= n; ++i) {
193+
dp[i] = max(nums[i - 1] + dp[i - 2], dp[i - 1]);
194+
}
195+
return dp[n];
196+
}
197+
};
198+
```
199+
82200
```cpp
83201
class Solution {
84202
public : int rob(vector<int>& nums) {
@@ -96,6 +214,54 @@ class Solution {
96214
97215
### **Go**
98216
217+
```go
218+
func rob(nums []int) int {
219+
n := len(nums)
220+
f := make([]int, n)
221+
for i := range f {
222+
f[i] = -1
223+
}
224+
var dfs func(int) int
225+
dfs = func(i int) int {
226+
if i >= n {
227+
return 0
228+
}
229+
if f[i] != -1 {
230+
return f[i]
231+
}
232+
f[i] = max(nums[i]+dfs(i+2), dfs(i+1))
233+
return f[i]
234+
}
235+
return dfs(0)
236+
}
237+
238+
func max(a, b int) int {
239+
if a > b {
240+
return a
241+
}
242+
return b
243+
}
244+
```
245+
246+
```go
247+
func rob(nums []int) int {
248+
n := len(nums)
249+
dp := make([]int, n+1)
250+
dp[1] = nums[0]
251+
for i := 2; i <= n; i++ {
252+
dp[i] = max(nums[i-1]+dp[i-2], dp[i-1])
253+
}
254+
return dp[n]
255+
}
256+
257+
func max(a, b int) int {
258+
if a > b {
259+
return a
260+
}
261+
return b
262+
}
263+
```
264+
99265
```go
100266
func rob(nums []int) int {
101267
a, b, n := 0, nums[0], len(nums)
@@ -115,6 +281,36 @@ func max(a, b int) int {
115281

116282
### **TypeScript**
117283

284+
```ts
285+
function rob(nums: number[]): number {
286+
const n = nums.length;
287+
const f = new Array(n).fill(-1);
288+
function dfs(i) {
289+
if (i >= n) {
290+
return 0;
291+
}
292+
if (f[i] != -1) {
293+
return f[i];
294+
}
295+
f[i] = Math.max(nums[i] + dfs(i + 2), dfs(i + 1));
296+
return f[i];
297+
}
298+
return dfs(0);
299+
}
300+
```
301+
302+
```ts
303+
function rob(nums: number[]): number {
304+
const n = nums.length;
305+
const dp = new Array(n + 1).fill(0);
306+
dp[1] = nums[0];
307+
for (let i = 2; i <= n; ++i) {
308+
dp[i] = Math.max(nums[i - 1] + dp[i - 2], dp[i - 1]);
309+
}
310+
return dp[n];
311+
}
312+
```
313+
118314
```ts
119315
function rob(nums: number[]): number {
120316
const dp = [0, 0];

0 commit comments

Comments
 (0)