42
42
43
43
<!-- 这里可写通用的实现逻辑 -->
44
44
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$ 为房屋数量。
46
70
47
71
<!-- tabs:start -->
48
72
49
73
### ** Python3**
50
74
51
75
<!-- 这里可写当前语言的特殊实现逻辑 -->
52
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
+ ``` 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
+
53
100
``` python
54
101
class Solution :
55
102
def rob (self , nums : List[int ]) -> int :
@@ -63,6 +110,45 @@ class Solution:
63
110
64
111
<!-- 这里可写当前语言的特殊实现逻辑 -->
65
112
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
+
66
152
``` java
67
153
class Solution {
68
154
public int rob (int [] nums ) {
@@ -79,6 +165,38 @@ class Solution {
79
165
80
166
### ** C++**
81
167
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
+
82
200
``` cpp
83
201
class Solution {
84
202
public : int rob(vector<int >& nums) {
@@ -96,6 +214,54 @@ class Solution {
96
214
97
215
### **Go**
98
216
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
+
99
265
``` go
100
266
func rob (nums []int ) int {
101
267
a , b , n := 0 , nums[0 ], len (nums)
@@ -115,6 +281,36 @@ func max(a, b int) int {
115
281
116
282
### ** TypeScript**
117
283
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
+
118
314
``` ts
119
315
function rob(nums : number []): number {
120
316
const dp = [0 , 0 ];
0 commit comments