Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5a0f5b2

Browse files
committed
feat: add solutions to lcof2 problem: No.101
lcof2 No.101.Partition Equal Subset Sum
1 parent 7b3594a commit 5a0f5b2

File tree

7 files changed

+262
-1
lines changed

7 files changed

+262
-1
lines changed

‎lcof2/剑指 Offer II 101. 分割等和子串/README.md‎

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,164 @@
3838

3939
<p><meta charset="UTF-8" />注意:本题与主站 416&nbsp;题相同:&nbsp;<a href="https://leetcode-cn.com/problems/partition-equal-subset-sum/">https://leetcode-cn.com/problems/partition-equal-subset-sum/</a></p>
4040

41-
4241
## 解法
4342

4443
<!-- 这里可写通用的实现逻辑 -->
4544

45+
题目可以转换为 `0-1` 背包问题,在 m 个数字中选出一些数字(每个数字只能使用一次),这些数字之和恰好等于 `s / 2`(s 表示所有数字之和)。
46+
47+
也可以用 DFS + 记忆化搜索。
48+
4649
<!-- tabs:start -->
4750

4851
### **Python3**
4952

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

5255
```python
56+
class Solution:
57+
def canPartition(self, nums: List[int]) -> bool:
58+
s = sum(nums)
59+
if s % 2 != 0:
60+
return False
61+
62+
m, n = len(nums), (s >> 1) + 1
63+
dp = [[False] * n for _ in range(m)]
64+
for i in range(m):
65+
dp[i][0] = True
66+
if nums[0] < n:
67+
dp[0][nums[0]] = True
68+
69+
for i in range(1, m):
70+
for j in range(n):
71+
dp[i][j] = dp[i - 1][j]
72+
if not dp[i][j] and nums[i] <= j:
73+
dp[i][j] = dp[i - 1][j - nums[i]]
74+
return dp[-1][-1]
75+
```
5376

77+
空间优化:
78+
79+
```python
80+
class Solution:
81+
def canPartition(self, nums: List[int]) -> bool:
82+
s = sum(nums)
83+
if s % 2 != 0:
84+
return False
85+
86+
m, n = len(nums), (s >> 1) + 1
87+
dp = [False] * n
88+
dp[0] = True
89+
if nums[0] < n:
90+
dp[nums[0]] = True
91+
92+
for i in range(1, m):
93+
for j in range(n - 1, nums[i] - 1, -1):
94+
dp[j] = dp[j] or dp[j - nums[i]]
95+
return dp[-1]
96+
```
97+
98+
DFS + 记忆化搜索:
99+
100+
```python
101+
class Solution:
102+
def canPartition(self, nums: List[int]) -> bool:
103+
s = sum(nums)
104+
if s % 2 != 0:
105+
return False
106+
target = s >> 1
107+
108+
@lru_cache(None)
109+
def dfs(i, s):
110+
nonlocal target
111+
if s > target or i >= len(nums):
112+
return False
113+
if s == target:
114+
return True
115+
return dfs(i + 1, s) or dfs(i + 1, s + nums[i])
116+
117+
return dfs(0, 0)
54118
```
55119

56120
### **Java**
57121

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

60124
```java
125+
class Solution {
126+
public boolean canPartition(int[] nums) {
127+
int s = 0;
128+
for (int x : nums) {
129+
s += x;
130+
}
131+
if (s % 2 != 0) {
132+
return false;
133+
}
134+
int m = nums.length, n = (s >> 1) + 1;
135+
boolean[] dp = new boolean[n];
136+
dp[0] = true;
137+
if (nums[0] < n) {
138+
dp[nums[0]] = true;
139+
}
140+
for (int i = 1; i < m; ++i) {
141+
for (int j = n - 1; j >= nums[i]; --j) {
142+
dp[j] = dp[j] || dp[j - nums[i]];
143+
}
144+
}
145+
return dp[n - 1];
146+
}
147+
}
148+
```
149+
150+
### **C++**
151+
152+
```cpp
153+
class Solution {
154+
public:
155+
bool canPartition(vector<int>& nums) {
156+
int s = 0;
157+
for (int x : nums) s += x;
158+
if (s % 2 != 0) return false;
159+
int m = nums.size(), n = (s >> 1) + 1;
160+
vector<bool> dp(n);
161+
dp[0] = true;
162+
if (nums[0] < n) dp[nums[0]] = true;
163+
for (int i = 1; i < m; ++i)
164+
{
165+
for (int j = n - 1; j >= nums[i]; --j)
166+
{
167+
dp[j] = dp[j] || dp[j - nums[i]];
168+
}
169+
}
170+
return dp[n - 1];
171+
}
172+
};
173+
```
61174
175+
### **Go**
176+
177+
```go
178+
func canPartition(nums []int) bool {
179+
s := 0
180+
for _, x := range nums {
181+
s += x
182+
}
183+
if s%2 != 0 {
184+
return false
185+
}
186+
m, n := len(nums), (s>>1)+1
187+
dp := make([]bool, n)
188+
dp[0] = true
189+
if nums[0] < n {
190+
dp[nums[0]] = true
191+
}
192+
for i := 1; i < m; i++ {
193+
for j := n - 1; j >= nums[i]; j-- {
194+
dp[j] = dp[j] || dp[j-nums[i]]
195+
}
196+
}
197+
return dp[n-1]
198+
}
62199
```
63200

64201
### **...**
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Solution {
2+
public:
3+
bool canPartition(vector<int>& nums) {
4+
int s = 0;
5+
for (int x : nums) s += x;
6+
if (s % 2 != 0) return false;
7+
int m = nums.size(), n = (s >> 1) + 1;
8+
vector<bool> dp(n);
9+
dp[0] = true;
10+
if (nums[0] < n) dp[nums[0]] = true;
11+
for (int i = 1; i < m; ++i)
12+
{
13+
for (int j = n - 1; j >= nums[i]; --j)
14+
{
15+
dp[j] = dp[j] || dp[j - nums[i]];
16+
}
17+
}
18+
return dp[n - 1];
19+
}
20+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
func canPartition(nums []int) bool {
2+
s := 0
3+
for _, x := range nums {
4+
s += x
5+
}
6+
if s%2 != 0 {
7+
return false
8+
}
9+
m, n := len(nums), (s>>1)+1
10+
dp := make([]bool, n)
11+
dp[0] = true
12+
if nums[0] < n {
13+
dp[nums[0]] = true
14+
}
15+
for i := 1; i < m; i++ {
16+
for j := n - 1; j >= nums[i]; j-- {
17+
dp[j] = dp[j] || dp[j-nums[i]]
18+
}
19+
}
20+
return dp[n-1]
21+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Solution {
2+
public boolean canPartition(int[] nums) {
3+
int s = 0;
4+
for (int x : nums) {
5+
s += x;
6+
}
7+
if (s % 2 != 0) {
8+
return false;
9+
}
10+
int m = nums.length, n = (s >> 1) + 1;
11+
boolean[] dp = new boolean[n];
12+
dp[0] = true;
13+
if (nums[0] < n) {
14+
dp[nums[0]] = true;
15+
}
16+
for (int i = 1; i < m; ++i) {
17+
for (int j = n - 1; j >= nums[i]; --j) {
18+
dp[j] = dp[j] || dp[j - nums[i]];
19+
}
20+
}
21+
return dp[n - 1];
22+
}
23+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution:
2+
def canPartition(self, nums: List[int]) -> bool:
3+
s = sum(nums)
4+
if s % 2 != 0:
5+
return False
6+
7+
m, n = len(nums), (s >> 1) + 1
8+
dp = [False] * n
9+
dp[0] = True
10+
if nums[0] < n:
11+
dp[nums[0]] = True
12+
13+
for i in range(1, m):
14+
for j in range(n - 1, nums[i] - 1, -1):
15+
dp[j] = dp[j] or dp[j - nums[i]]
16+
return dp[-1]

‎solution/0400-0499/0416.Partition Equal Subset Sum/README.md‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040

4141
题目可以转换为 `0-1` 背包问题,在 m 个数字中选出一些数字(每个数字只能使用一次),这些数字之和恰好等于 `s / 2`(s 表示所有数字之和)。
4242

43+
也可以用 DFS + 记忆化搜索。
44+
4345
<!-- tabs:start -->
4446

4547
### **Python3**
@@ -89,6 +91,28 @@ class Solution:
8991
return dp[-1]
9092
```
9193

94+
DFS + 记忆化搜索:
95+
96+
```python
97+
class Solution:
98+
def canPartition(self, nums: List[int]) -> bool:
99+
s = sum(nums)
100+
if s % 2 != 0:
101+
return False
102+
target = s >> 1
103+
104+
@lru_cache(None)
105+
def dfs(i, s):
106+
nonlocal target
107+
if s > target or i >= len(nums):
108+
return False
109+
if s == target:
110+
return True
111+
return dfs(i + 1, s) or dfs(i + 1, s + nums[i])
112+
113+
return dfs(0, 0)
114+
```
115+
92116
### **Java**
93117

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

‎solution/0400-0499/0416.Partition Equal Subset Sum/README_EN.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,26 @@ class Solution:
7878
return dp[-1]
7979
```
8080

81+
```python
82+
class Solution:
83+
def canPartition(self, nums: List[int]) -> bool:
84+
s = sum(nums)
85+
if s % 2 != 0:
86+
return False
87+
target = s >> 1
88+
89+
@lru_cache(None)
90+
def dfs(i, s):
91+
nonlocal target
92+
if s > target or i >= len(nums):
93+
return False
94+
if s == target:
95+
return True
96+
return dfs(i + 1, s) or dfs(i + 1, s + nums[i])
97+
98+
return dfs(0, 0)
99+
```
100+
81101
### **Java**
82102

83103
```java

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /