LeetCode 416 分割等和子集

这篇博客探讨了如何利用动态规划算法解决一个数学问题:判断数组中的元素是否能组成目标和。当所有元素之和为偶数时,目标是找到两个子集,它们的和相等且等于总和的一半。博主通过构建dp数组,定义了状态转移方程,实现了从全集到目标子集的转化,并给出了Go语言实现的代码示例。
摘要由CSDN通过智能技术生成

 全部元素相加得到和,如果为奇数,必然无法满足调节,如果为偶数,那么目标子集和已经确定(全部元素和的一半),只要令一个子集的和满足目标,那么可以直接返回 true。所以原题就可以转变为计算nums中的数字能否组成 targetSum。

对于这种问题,首先可以遍历全部的子集和,但可能会造成较大的时间复杂度,出现超出运行时间的错误。由此想到了动态规划(自信一点,想到了就想下去,不要老想着看答案!!),构建 dp []bool  数组,其中dp[i]表示nums中是否存在子数组满足其和==i,最后返回dp[targetSum]即可。可以构建其状态转移方程如下:

dp[i]=dp[i] || (dp[i-num[j]] && num[j])

注意:在构建dp时,因为用下标i表示可以组成的和,所以数组长度应该设置为targetSum+1,同时将dp[0]设置为true

GO

func canPartition(nums []int) bool {
    var sum, targetSum int=0, 0
    var dp []bool
    for _, v:=range nums{ sum+=v }
    if sum%2!=0 { return false }
    targetSum=sum/2
    dp=make([]bool, targetSum+1)
    dp[0]=true
    for _, v:=range nums{
        for i:=targetSum; i>=v; i--{
            dp[i]=dp[i] || dp[i-v]
        }
    }
    return dp[targetSum]
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值