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];
    }
};
相关推荐
大鱼>7 分钟前
因子挖掘+回测+RL交易:量化金融完整系统
人工智能·深度学习·算法·金融
c238562 小时前
《枚举算法 “翻译官”:用 enum class 给 “游游的礼盒” 算分》
c语言·c++·算法
noipp2 小时前
推荐题目:洛谷 P5843 [SCOI2012] Blinker 的噩梦
c语言·数据结构·c++·算法·游戏·洛谷·luogu
极客BIM工作室2 小时前
OpenCascade 倒角(Chamfer)算法完整逻辑解析
算法
冻柠檬飞冰走茶2 小时前
PTA基础编程题目集 7-20 打印九九口诀表(C语言实现)
c语言·开发语言·数据结构·算法
鱼子星_2 小时前
《算 · 法》题目解析篇(1):最近公共祖先问题,线段树,最长回文子序列
c++·算法·动态规划·递归
雾喔2 小时前
算法练习5
算法·代理模式
问商十三载2 小时前
RAG 检索召回越多越好?2026 信噪比模型深度解析
人工智能·算法·机器学习
额恩662 小时前
ResearchPilot 第三阶段总结报告
python·算法
Hi李耶3 小时前
【LeetCode】9-回文数
算法·leetcode·职场和发展