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];
    }
};
相关推荐
木木子225 小时前
# 密码强度检测深度解析:正则表达式实时分析、多维度评分算法与可视化反馈
mysql·算法·华为·正则表达式·harmonyos
Sw1zzle8 小时前
算法入门(四):二叉树 - 递归遍历三件套
算法·leetcode
万法若空8 小时前
【算法-查找】查找算法
java·数据结构·算法
海石8 小时前
子树怎么找?树的3种遍历方式来帮忙!
算法·leetcode
海石8 小时前
难度分 1588:思路 + 技巧 = AC
算法·leetcode
珠海西格电力12 小时前
云边端协同架构:零碳园区管理系统的技术底座
大数据·运维·人工智能·算法·架构·能源
还有多久拿退休金14 小时前
让飞书知识库跟着 commit 自己长:一套自动化知识库的真实实现
前端·算法·架构
KaMeidebaby15 小时前
卡梅德生物技术快报|小 RNA 适配体合成 + 多方法亲和力表征全流程标准化操作手册
前端·网络·数据库·人工智能·算法
是Dream呀15 小时前
基于深度学习的人类行为识别算法研究
人工智能·深度学习·算法
happyprince16 小时前
03_NVIDIA_ModelOpt-量化算法深入
人工智能·深度学习·算法