題目描述
給定一個只包含正整數的非空數組。是否可以將這個數組分割成兩個子集,使得兩個子集的元素和相等。
注意:
- 每個數組中的元素不會超過 100
- 數組的大小不會超過 200
示例 1:
輸入: [1, 5, 11, 5]
輸出: true
解釋: 數組可以分割成 [1, 5, 5] 和 [11].
示例 2:
輸入: [1, 2, 3, 5]
輸出: false
解釋: 數組不能分割成兩個元素和相等的子集.
分析
這道題其實可以變成是0-1揹包問題,利用動態規劃思想做題:
- 狀態表示:,表示前n個數,是否能找到和爲C的數字組合,能爲
True
,不能爲False
。- 如果不考慮第n個元素,那麼情況等於前n-1個元素的情況即
- 如果考慮第n個元素,那麼情況等於前n-1個元素的子集和加上第n個元素的和可以組成和C,C-nums[n]表示前n-1個元素可以組成和爲C-nums[n],那麼加上第n個元素nums[n],和即可C,可以組成子集。
- 狀態轉移公式:
- 邊界:0邊界爲 。
代碼
class Solution:
def canPartition(self, nums: List[int]) -> bool:
sumNums = sum(nums)
if sumNums%2==1:
return False
sumOfHalf = sumNums//2
length = len(nums)
dp = [[False for i in range(sumOfHalf+1)] for j in range(length+1)]
for i in range(length+1):
dp[i][0] = True
for i in range(1, length+1):
for j in range(1, int(sumOfHalf)+1):
dp[i][j] = dp[i-1][j]
if j>=nums[i-1]:
dp[i][j] = dp[i][j] or dp[i-1][j-nums[i-1]]
return dp[length][sumOfHalf]