Cover image for leetcode热题100 P416 分割等和子集

leetcode热题100 P416 分割等和子集


时间轴

时间轴

2026-03-21

init

动态规划

题目:

将子数组求和,然后将和除以2,转化找到数组一个子集为总和的一半,即为 0-1 背包问题

dp[i][j] 表示从数组的 [0,i] 下标范围内选取若干个正整数(可以是 0 个),是否存在一种选取方案使得被选取的正整数的和等于 j。初始时,dp 中的全部元素都是 false。

初始化:

  • 如果不选取任何正整数,则被选取的正整数之和等于 0。因此对于所有 0 ≤ i < n,都有 dp[i][0]=true。
  • 当 i==0 时,只有一个正整数 nums[0] 可以被选取,因此 dp[0]nums[0]]=true。

状态转移:

  • dp[i][j] = dp[i−1][j] ∣ dp[i−1][j−nums[i]](j >= nums[i])
  • dp[i][j] = dp[i-1][j](j < nums[i])
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
#include <vector>using std::vector;class Solution {    public:        bool canPartition(vector<int> &nums)        {                int i, j, n = nums.size();                int sum = 0, target;                for (i = 0; i < n; i++)                        sum += nums[i];                if (sum % 2 != 0) // 奇数                        return false;                target = sum / 2;                for (i = 0; i < n; i++) { // 有一个数超过总和的一半                        if (nums[0] > target)                                return false;                }                // 0-1 背包问题                // dp[i][j] 表示从数组的 [0,i] 下标范围内选取若干个正整数(可以是 0 个)                // 是否存在一种选取方案使得被选取的正整数的和等于 j。初始时,dp 中的全部元素都是 false。                vector<vector<bool> > dp(n, vector<bool>(target + 1, false));                // 如果不选取任何正整数,则被选取的正整数之和等于 0。因此对于所有 0 ≤ i < n,都有 dp[i][0]=true。                for (i = 0; i < n; i++)                        dp[i][0] = true;                // 当 i==0 时,只有一个正整数 nums[0] 可以被选取,因此 dp[0][nums[0]]=true。                dp[0][nums[0]] = true;                // dp[i][j] = dp[i−1][j] ∣ dp[i−1][j−nums[i]] (j >= nums[i])                // dp[i][j] = dp[i-1][j] (j < nums[i])                for (i = 1; i < n; i++) {                        for (j = 1; j <= target; j++) {                                if (j >= nums[i])                                        dp[i][j] = dp[i - 1][j] | dp[i - 1][j - nums[i]];                                else                                        dp[i][j] = dp[i - 1][j];                        }                }                return dp[n - 1][target];        }};
评论加载中…