416. 分割等和子集
分析
典型的 01
背包问题,我们需要判断是否存在一个子集,其元素和为 sum / 2
,其中 sum
是数组 nums
的元素总和
- 特殊情况处理:
- 如果数组总和
sum
是奇数,则无法分成两个相等的子集,直接返回false
- 如果数组总和
- 动态规划定义:
- 定义一个布尔数组
f
,其中f[j]
表示是否可以从数组中选取一些元素,使得这些元素的和为j
- 初始化
f[0] = true
,表示总和为0
的情况总是成立(即不选任何元素)
- 定义一个布尔数组
- 状态转移方程:
- 遍历数组
nums
中的每个数nums[i]
,从目标值target
开始往下更新:f[j] = f[j] || f[j - nums[i]]
- 表示如果在之前能凑出
j - nums[i]
,则加入当前数字后也能凑出j
- 遍历数组
- 最终结果:
- 如果能凑出目标值
sum / 2
,即f[target] == true
,则可以分成两个相等的子集
- 如果能凑出目标值
时间复杂度
- 外层循环遍历数组
n
次 - 内层循环遍历目标值
target
次
总时间复杂度 O(n * target)
空间复杂度
空间复杂度为 O(target)
C++代码
|
|