Leetcode题解系列——416. Partition Equal Subset Sum(c++版)

本文探讨了如何通过动态规划解决子集划分问题,将其类比为背包问题,旨在判断一个数组是否能被分割成两个和相等的子集。通过计算数组总和并检查其是否为偶数,确定目标子集和,再使用动态规划方法,以状态转移方程dp[i]=dp[i]||dp[i-num]判断子集的存在性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:416. Partition Equal Subset Sum

题目大意:题目给出一个数组,分割成两个集合,判断这两个集合的和相等。

一.算法设计

这是一道经典的动态规划问题,判断子集合的和是否相等,由于集合的组成需要指数的构造时间,不符合题目要求的时间复杂度。这道算法题可以类比成背包问题。

既然要划分成两个集合的和都相等,那么我们先算出这个集合的总和,这个sum必须为偶数,才能划分成功

然后,这个sum的一半就是我们所要达到的目标。为什么说它像背包问题呢,因为这个sum的一半可以比作背包的容量w,我们想利用数组中的元素恰好填满这个w容量的背包,且其中的元素不能重复有且只有一个。

因此我们可以写出状态转移方程

	dp[i] = dp[i] || dp[i-num]

其中dp[i]表达的是选取数组的元素,是否可以恰好填满容量i的背包。 若dp为1,则证明可以填充;dp为0则不能。

最后,我们只需要判断dp[target]是否为1即可,判断是否存在这样的划分。

注意点:
  1. 这里的遍历要求第一层遍历nums数组中的元素,第二层要从target值开始从后到前这样来遍历,避免数组越界的情况。

二.算法实现

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int sum = accumulate(nums.begin(), nums.end(), 0);
        if(sum%2 != 0) return false;
        int target = sum / 2;
        vector<int> dp(target+1,0);
        dp[0] = 1;
        for(int num : nums){           
            for(int i = target; i >= num ; i--){
                dp[i] = dp[i] || dp[i-num];
            }
        }
        return dp[target];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值