LeetCode:89.分割等和子集

目录

1.分割等和子集


1.分割等和子集

对于这道题,我们可以先计算数组的总和,如果总和为奇数的话,就不需要后面的判断了,奇数和肯定无法分割等和子集

和sum为偶数后,我们可以将其看作一个背包问题,我们需要从数组中找到和为sum/2的数组,所以我们就将其转化为背包问题

设dpij表示能否从前i个数字中找到和为j的数组,分为以下情况:

  1. 选择i这个数,dpij = dpi - 1j - nums\[i]
  2. 不选择i这个数,dpij = dpi - 1j

我们取这两种结果的或运算,只要满足一种即可

cpp 复制代码
class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int n = nums.size(), sum = 0;
        for(auto x : nums) sum += x;
        if(sum % 2 == 1) return false;
        int aim = sum / 2;
        vector<vector<bool>> dp(n + 1, vector<bool>(aim + 1));
        for(int i = 0; i <= n; i++) dp[i][0] = true;
        for(int i = 1; i <= n; i++)
            for(int j = 0; j <= aim; j++)
            {
                dp[i][j] = dp[i - 1][j];
                if(j >= nums[i - 1])
                    dp[i][j] = dp[i][j] || dp[i - 1][j - nums[i - 1]];
            }
        return dp[n][aim];
    }
};

空间优化后

cpp 复制代码
class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int n = nums.size(), sum = 0;
        for(auto x : nums) sum += x;
        if(sum % 2 == 1) return false;
        int aim = sum / 2;
        vector<bool> dp(aim + 1);
        dp[0] = true;
        for(int i = 1; i <= n; i++)
            for(int j = aim; j >= nums[i - 1]; j--)
                dp[j] = dp[j] || dp[j - nums[i - 1]];
        return dp[aim];
    }
};
相关推荐
通信小呆呆3 小时前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
benben0444 小时前
强化学习之DQN算法族(基于gymnasium开发)
算法
何以解忧,唯有..5 小时前
Go语言循环语句详解:for、range与循环控制
开发语言·算法·golang
想吃火锅10056 小时前
【leetcode】88.合并两个有序数组js
算法
生成论实验室6 小时前
机器人:一个自主运动的系统
人工智能·算法·语言模型·机器人·自动驾驶·agi·安全架构
Qres8216 小时前
算法复键——树状数组
数据结构·算法
H178535090966 小时前
SolidWorks第四部分_直接实体建模特征9_替换面原理
线性代数·算法·机器学习·3d建模·solidworks
不会就选b7 小时前
算法日常・每日刷题--<二分查找>3
算法
绿算技术7 小时前
Mooncake 与绿算ForinnBase GroundPool如何联手打破推理僵局?
科技·算法·架构