LeetCode:89.分割等和子集

目录

1.分割等和子集


1.分割等和子集

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

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

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

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

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

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];
    }
};
相关推荐
Croa-vo2 分钟前
TikTok 数据工程师三轮 VO 超详细面经:技术深挖 + 建模推导 + 压力测试全记录
javascript·数据结构·经验分享·算法·面试
蘑菇小白9 分钟前
时间复杂度
数据结构·算法
czlczl2002092532 分钟前
算法:组合问题
算法·leetcode·职场和发展
CoderYanger35 分钟前
优选算法-字符串:63.二进制求和
java·开发语言·算法·leetcode·职场和发展·1024程序员节
Cx330❀1 小时前
C++ STL set 完全指南:从基础用法到实战技巧
开发语言·数据结构·c++·算法·leetcode·面试
阿昭L2 小时前
堆结构与堆排序
数据结构·算法
2***57422 小时前
人工智能在智能投顾中的算法
人工智能·算法
草莓熊Lotso2 小时前
《算法闯关指南:动态规划算法--斐波拉契数列模型》--01.第N个泰波拉契数,02.三步问题
开发语言·c++·经验分享·笔记·其他·算法·动态规划
2501_941805313 小时前
智慧零售平台中的多语言语法引擎与实时推荐系统实践
leetcode
mit6.8249 小时前
bfs|栈
算法