【LeetCode 中等題】75-分割等和子集
阿新 • • 發佈:2019-01-14
題目描述:給定一個只包含正整數的非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。
注意:
- 每個陣列中的元素不會超過 100
- 陣列的大小不會超過 200
示例 1:
輸入: [1, 5, 11, 5] 輸出: true 解釋: 陣列可以分割成 [1, 5, 5] 和 [11].示例 2:
輸入: [1, 2, 3, 5] 輸出: false 解釋: 陣列不能分割成兩個元素和相等的子集.
解法1。這是個典型的揹包問題,能不能找到若干各元素使其和等於sum/2(sum必須是可均分的,不然返回False)。
class Solution(object): def canPartition(self, nums): """ :type nums: List[int] :rtype: bool """ if not nums: return False summ = sum(nums) if summ & 1: return False memo = [[-1 for _ in range(summ//2+1)] for _ in range(len(nums))] return self.helper(nums, 0, summ//2, memo) def helper(self, nums, index, summ, memo): if summ == 0: return True if index >= len(nums) or summ < 0: return False if memo[index][summ] != -1: return memo[index][summ] == 1 if self.helper(nums, index+1, summ, memo) or self.helper(nums, index+1, summ-nums[index], memo): memo[index][summ] = 1 else: memo[index][summ] = 0 return memo[index][summ] == 1
解法2。改寫成DP,自底向上
class Solution(object): def canPartition(self, nums): """ :type nums: List[int] :rtype: bool """ if not nums: return False summ = sum(nums) if summ & 1: return False memo = [False for _ in range(summ//2+1)] c = summ//2 for i in range(c+1): memo[i] = True if nums[0] == i else False for i in range(1, len(nums)): j=c while j >= nums[i]: memo[j] = memo[j] or memo[j-nums[i]] j -= 1 return memo[-1]