42
42
43
43
<!-- 这里可写通用的实现逻辑 -->
44
44
45
- ** 方法一:记忆化搜索 **
45
+ ** 方法一:动态规划 **
46
46
47
- 我们设计函数 $dfs(i)$ 表示从第 $i$ 间房屋开始偷窃,能偷窃到的最高金额。答案为 $dfs(0) $。
47
+ 我们定义 $f [ i ] $ 表示前 $i$ 间房屋能偷窃到的最高总金额,初始时 $f [ 0 ] =0$, $f [ 1 ] =nums [ 0 ] $。
48
48
49
- 对于第 $i$ 间房屋,有偷窃和不偷窃两种选择。如果偷窃,那么下一间房屋就不能偷窃,偷窃总金额为当前房屋金额加上下下间房屋开始的偷窃最高金额,即 $nums [ i ] + dfs(i + 2)$。如果不偷窃,那么下一间房屋就可以偷窃,偷窃总金额为下一间房屋开始的偷窃最高金额,即 $dfs(i + 1)$。两种选择取最大值作为函数 $dfs(i)$ 的返回值。
49
+ 考虑 $i \gt 1$ 的情况,第 $i$ 间房屋有两个选项:
50
50
51
- 我们可以使用记忆化搜索,避免重复计算。
51
+ - 不偷窃第 $i$ 间房屋,偷窃总金额为 $f[ i-1] $;
52
+ - 偷窃第 $i$ 间房屋,偷窃总金额为 $f[ i-2] +nums[ i-1] $;
52
53
53
- 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为房屋数量。
54
+ 因此,我们可以得到状态转移方程:
54
55
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
+ $$
56
64
57
- 我们也可以将记忆化搜索改成动态规划 。
65
+ 最终的答案即为 $f [ n ] $,其中 $n$ 是数组的长度 。
58
66
59
- 定义 $dp [ i ] $ 表示偷窃前 $i$ 个房屋能得到的最高金额。答案为 $dp [ n ] $ 。
67
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组长度 。
60
68
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)$。
70
70
71
71
<!-- tabs:start -->
72
72
73
73
### ** Python3**
74
74
75
75
<!-- 这里可写当前语言的特殊实现逻辑 -->
76
76
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
77
``` python
90
78
class Solution :
91
79
def rob (self , nums : List[int ]) -> int :
92
80
n = len (nums)
93
- dp = [0 ] * (n + 1 )
94
- dp [1 ] = nums[0 ]
81
+ f = [0 ] * (n + 1 )
82
+ f [1 ] = nums[0 ]
95
83
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]
98
86
```
99
87
100
88
``` python
101
89
class Solution :
102
90
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
107
95
```
108
96
109
97
### ** Java**
110
98
111
99
<!-- 这里可写当前语言的特殊实现逻辑 -->
112
100
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
101
``` java
139
102
class Solution {
140
103
public int rob (int [] nums ) {
141
104
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 ];
144
107
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 ]);
146
109
}
147
- return dp [n];
110
+ return f [n];
148
111
}
149
112
}
150
113
```
151
114
152
115
``` java
153
116
class Solution {
154
117
public int rob (int [] nums ) {
155
- int a = 0 , b = nums[0 ];
118
+ int f = 0 , g = nums[0 ];
156
119
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 ;
160
123
}
161
- return b ;
124
+ return g ;
162
125
}
163
126
}
164
127
```
@@ -170,29 +133,13 @@ class Solution {
170
133
public:
171
134
int rob(vector<int >& nums) {
172
135
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] ;
192
139
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] );
194
141
}
195
- return dp [n];
142
+ return f [ n] ;
196
143
}
197
144
};
198
145
```
@@ -201,14 +148,13 @@ public:
201
148
class Solution {
202
149
public:
203
150
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;
210
156
}
211
- return b ;
157
+ return g ;
212
158
}
213
159
};
214
160
```
@@ -218,41 +164,12 @@ public:
218
164
``` go
219
165
func rob (nums []int ) int {
220
166
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 ]
252
169
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 ])
254
171
}
255
- return dp [n]
172
+ return f [n]
256
173
}
257
174
258
175
func max (a , b int ) int {
@@ -265,11 +182,11 @@ func max(a, b int) int {
265
182
266
183
``` go
267
184
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 )
271
188
}
272
- return b
189
+ return g
273
190
}
274
191
275
192
func max (a , b int ) int {
@@ -285,40 +202,22 @@ func max(a, b int) int {
285
202
``` ts
286
203
function rob(nums : number []): number {
287
204
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 ];
308
207
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 ]);
310
209
}
311
- return dp [n ];
210
+ return f [n ];
312
211
}
313
212
```
314
213
315
214
``` ts
316
215
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 )];
320
219
}
321
- return dp [ 1 ] ;
220
+ return g ;
322
221
}
323
222
```
324
223
@@ -327,11 +226,11 @@ function rob(nums: number[]): number {
327
226
``` rust
328
227
impl Solution {
329
228
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 )]
333
232
}
334
- dp [1 ]
233
+ f [1 ]
335
234
}
336
235
}
337
236
```
0 commit comments