Skip to content

Commit 3d725b4

Browse files
authored
feat: add solutions to lc/lcof problems (#1444)
* lc No.0198 & lcof2 No.089.House Robber * lc No.0213 & lcof2 No.090.House Robber II
1 parent 5841631 commit 3d725b4

30 files changed

+610
-483
lines changed

lcof2/剑指 Offer II 089. 房屋偷盗/README.md

+142-40
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,31 @@
4444

4545
<!-- 这里可写通用的实现逻辑 -->
4646

47-
简单动态规划,用 `dp[i]` 表示 `0 ~ i` 的房子能偷到的最高金额
47+
**方法一:动态规划**
48+
49+
我们定义 $f[i]$ 表示前 $i$ 间房屋能偷窃到的最高总金额,初始时 $f[0]=0$, $f[1]=nums[0]$。
50+
51+
考虑 $i \gt 1$ 的情况,第 $i$ 间房屋有两个选项:
52+
53+
- 不偷窃第 $i$ 间房屋,偷窃总金额为 $f[i-1]$;
54+
- 偷窃第 $i$ 间房屋,偷窃总金额为 $f[i-2]+nums[i-1]$;
55+
56+
因此,我们可以得到状态转移方程:
57+
58+
$$
59+
f[i]=
60+
\begin{cases}
61+
0, & i=0 \\
62+
nums[0], & i=1 \\
63+
\max(f[i-1],f[i-2]+nums[i-1]), & i \gt 1
64+
\end{cases}
65+
$$
66+
67+
最终的答案即为 $f[n]$,其中 $n$ 是数组的长度。
68+
69+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组长度。
70+
71+
注意到当 $i \gt 2$ 时,$f[i]$ 只和 $f[i-1]$ 与 $f[i-2]$ 有关,因此我们可以使用两个变量代替数组,将空间复杂度降到 $O(1)$。
4872

4973
<!-- tabs:start -->
5074

@@ -55,15 +79,21 @@
5579
```python
5680
class Solution:
5781
def rob(self, nums: List[int]) -> int:
58-
if len(nums) == 1:
59-
return nums[0]
60-
6182
n = len(nums)
62-
dp = [0] * n
63-
dp[0], dp[1] = nums[0], max(nums[0], nums[1])
64-
for i in range(2, n):
65-
dp[i] = max(dp[i - 2] + nums[i], dp[i - 1])
66-
return dp[n - 1]
83+
f = [0] * (n + 1)
84+
f[1] = nums[0]
85+
for i in range(2, n + 1):
86+
f[i] = max(f[i - 1], f[i - 2] + nums[i - 1])
87+
return f[n]
88+
```
89+
90+
```python
91+
class Solution:
92+
def rob(self, nums: List[int]) -> int:
93+
f = g = 0
94+
for x in nums:
95+
f, g = max(f, g), f + x
96+
return max(f, g)
6797
```
6898

6999
### **Java**
@@ -73,17 +103,27 @@ class Solution:
73103
```java
74104
class Solution {
75105
public int rob(int[] nums) {
76-
if (nums.length == 1) {
77-
return nums[0];
78-
}
79106
int n = nums.length;
80-
int[] dp = new int[n];
81-
dp[0] = nums[0];
82-
dp[1] = Math.max(nums[0], nums[1]);
83-
for (int i = 2; i < n; i++) {
84-
dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
107+
int[] f = new int[n + 1];
108+
f[1] = nums[0];
109+
for (int i = 2; i <= n; ++i) {
110+
f[i] = Math.max(f[i - 1], f[i - 2] + nums[i - 1]);
85111
}
86-
return dp[n - 1];
112+
return f[n];
113+
}
114+
}
115+
```
116+
117+
```java
118+
class Solution {
119+
public int rob(int[] nums) {
120+
int f = 0, g = 0;
121+
for (int x : nums) {
122+
int ff = Math.max(f, g);
123+
g = f + x;
124+
f = ff;
125+
}
126+
return Math.max(f, g);
87127
}
88128
}
89129
```
@@ -94,17 +134,29 @@ class Solution {
94134
class Solution {
95135
public:
96136
int rob(vector<int>& nums) {
97-
if (nums.size() == 1) {
98-
return nums[0];
99-
}
100137
int n = nums.size();
101-
vector<int> dp(n, 0);
102-
dp[0] = nums[0];
103-
dp[1] = max(nums[0], nums[1]);
104-
for (int i = 2; i < n; i++) {
105-
dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
138+
int f[n + 1];
139+
memset(f, 0, sizeof(f));
140+
f[1] = nums[0];
141+
for (int i = 2; i <= n; ++i) {
142+
f[i] = max(f[i - 1], f[i - 2] + nums[i - 1]);
106143
}
107-
return dp[n - 1];
144+
return f[n];
145+
}
146+
};
147+
```
148+
149+
```cpp
150+
class Solution {
151+
public:
152+
int rob(vector<int>& nums) {
153+
int f = 0, g = 0;
154+
for (int& x : nums) {
155+
int ff = max(f, g);
156+
g = f + x;
157+
f = ff;
158+
}
159+
return max(f, g);
108160
}
109161
};
110162
```
@@ -113,25 +165,75 @@ public:
113165

114166
```go
115167
func rob(nums []int) int {
116-
if len(nums) == 1 {
117-
return nums[0]
168+
n := len(nums)
169+
f := make([]int, n+1)
170+
f[1] = nums[0]
171+
for i := 2; i <= n; i++ {
172+
f[i] = max(f[i-1], f[i-2]+nums[i-1])
118173
}
174+
return f[n]
175+
}
119176

120-
n := len(nums)
121-
dp := make([]int, n)
122-
dp[0] = nums[0]
123-
dp[1] = max(nums[0], nums[1])
124-
for i := 2; i < n; i++ {
125-
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
177+
func max(a, b int) int {
178+
if a > b {
179+
return a
126180
}
127-
return dp[n-1]
181+
return b
128182
}
183+
```
129184

130-
func max(x, y int) int {
131-
if x > y {
132-
return x
185+
```go
186+
func rob(nums []int) int {
187+
f, g := 0, 0
188+
for _, x := range nums {
189+
f, g = max(f, g), f+x
133190
}
134-
return y
191+
return max(f, g)
192+
}
193+
194+
func max(a, b int) int {
195+
if a > b {
196+
return a
197+
}
198+
return b
199+
}
200+
```
201+
202+
### **TypeScript**
203+
204+
```ts
205+
function rob(nums: number[]): number {
206+
const n = nums.length;
207+
const f: number[] = Array(n + 1).fill(0);
208+
f[1] = nums[0];
209+
for (let i = 2; i <= n; ++i) {
210+
f[i] = Math.max(f[i - 1], f[i - 2] + nums[i - 1]);
211+
}
212+
return f[n];
213+
}
214+
```
215+
216+
```ts
217+
function rob(nums: number[]): number {
218+
let [f, g] = [0, 0];
219+
for (const x of nums) {
220+
[f, g] = [Math.max(f, g), f + x];
221+
}
222+
return Math.max(f, g);
223+
}
224+
```
225+
226+
### **Rust**
227+
228+
```rust
229+
impl Solution {
230+
pub fn rob(nums: Vec<i32>) -> i32 {
231+
let mut f = [0, 0];
232+
for x in nums {
233+
f = [f[0].max(f[1]), f[0] + x]
234+
}
235+
f[0].max(f[1])
236+
}
135237
}
136238
```
137239

Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
class Solution {
2-
public:
3-
int rob(vector<int>& nums) {
4-
if (nums.size() == 1) {
5-
return nums[0];
6-
}
7-
int n = nums.size();
8-
vector<int> dp(n, 0);
9-
dp[0] = nums[0];
10-
dp[1] = max(nums[0], nums[1]);
11-
for (int i = 2; i < n; i++) {
12-
dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
13-
}
14-
return dp[n - 1];
15-
}
16-
};
1+
class Solution {
2+
public:
3+
int rob(vector<int>& nums) {
4+
int f = 0, g = 0;
5+
for (int& x : nums) {
6+
int ff = max(f, g);
7+
g = f + x;
8+
f = ff;
9+
}
10+
return max(f, g);
11+
}
12+
};
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
11
func rob(nums []int) int {
2-
if len(nums) == 1 {
3-
return nums[0]
2+
f, g := 0, 0
3+
for _, x := range nums {
4+
f, g = max(f, g), f+x
45
}
5-
6-
n := len(nums)
7-
dp := make([]int, n)
8-
dp[0] = nums[0]
9-
dp[1] = max(nums[0], nums[1])
10-
for i := 2; i < n; i++ {
11-
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
12-
}
13-
return dp[n-1]
6+
return max(f, g)
147
}
158

16-
func max(x, y int) int {
17-
if x > y {
18-
return x
9+
func max(a, b int) int {
10+
if a > b {
11+
return a
1912
}
20-
return y
13+
return b
2114
}
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
class Solution {
2-
public int rob(int[] nums) {
3-
if (nums.length == 1) {
4-
return nums[0];
5-
}
6-
int n = nums.length;
7-
int[] dp = new int[n];
8-
dp[0] = nums[0];
9-
dp[1] = Math.max(nums[0], nums[1]);
10-
for (int i = 2; i < n; i++) {
11-
dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
12-
}
13-
return dp[n - 1];
14-
}
15-
}
1+
class Solution {
2+
public int rob(int[] nums) {
3+
int f = 0, g = 0;
4+
for (int x : nums) {
5+
int ff = Math.max(f, g);
6+
g = f + x;
7+
f = ff;
8+
}
9+
return Math.max(f, g);
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
class Solution:
2-
def rob(self, nums: List[int]) -> int:
3-
if len(nums) == 1:
4-
return nums[0]
5-
6-
n = len(nums)
7-
dp = [0] * n
8-
dp[0], dp[1] = nums[0], max(nums[0], nums[1])
9-
for i in range(2, n):
10-
dp[i] = max(dp[i - 2] + nums[i], dp[i - 1])
11-
return dp[n - 1]
1+
class Solution:
2+
def rob(self, nums: List[int]) -> int:
3+
f = g = 0
4+
for x in nums:
5+
f, g = max(f, g), f + x
6+
return max(f, g)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
impl Solution {
2+
pub fn rob(nums: Vec<i32>) -> i32 {
3+
let mut f = [0, 0];
4+
for x in nums {
5+
f = [f[0].max(f[1]), f[0] + x]
6+
}
7+
f[0].max(f[1])
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function rob(nums: number[]): number {
2+
let [f, g] = [0, 0];
3+
for (const x of nums) {
4+
[f, g] = [Math.max(f, g), f + x];
5+
}
6+
return Math.max(f, g);
7+
}

0 commit comments

Comments
 (0)