描述
给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
注意:
每个数组中的元素不会超过 100
数组的大小不会超过 200
示例 1:
输入: [1, 5, 11, 5]
输出: true
解释: 数组可以分割成 [1, 5, 5] 和 [11].
示例 2:
输入: [1, 2, 3, 5]
输出: false
解释: 数组不能分割成两个元素和相等的子集.
思路
假设数组所有数的和为sum 那么找相等子集就相当于在数组中找是否存在子集的和为sum/2 且sum必须为偶数
动态规划问题
1. 找公式
假设 dp[i][sum] 代表 前i个数中是否存在子集和为sum
如果nums[i] > sum
dp[i][sum] = dp[i-1][sum]
如果nums[i] <= sum
dp[i][sum] = dp[i-1][sum] || dp[i-1][sum-nums[i-1]]
2. 初始值
dp[0][0] = true
dp[0][other] = false
实现
func canPartition(nums []int) bool {
var sum int
var l = len(nums)
for _, num := range nums{
sum += num
}
if sum %2 == 1{
return false
}
target := sum/2
dp := make([][]bool, l+1)
dp[0] = make([]bool, target + 1)
dp[0][0] = true
for i:= 1; i <= l; i++{
dp[i] = make([]bool, target + 1)
for j := 0; j <= target; j++{
if nums[i-1] > j{
dp[i][j] = dp[i-1][j]
}else{
dp[i][j] = dp[i-1][j] ||dp[i-1][j - nums[i-1]]
}
}
}
return dp[l][target]
}