考察的知识点:动态规划;
解答方法分析:
- 定义一个二维数组dp,dp[i][j]表示在前i个元素中是否存在一个子集,它们的和恰好为j。初始时,dp[0][0]为true。
- 逐个考虑每个元素weights[i],对于第i个元素,有两种情况:当weights[i]大于当前的目标值j时,dp[i][j]的值与dp[i-1][j]相同,表示前i-1个元素已经可以组成j的和,第i个元素不用考虑,所以dp[i][j] = dp[i-1][j]。当weights[i]小于等于当前的目标值j时,dp[i][j]的值等于dp[i-1][j]或dp[i-1][j-weights[i]],即dp[i][j] = dp[i-1][j] || dp[i-1][j-weights[i]]。
- 如果dp[n-1][target]为true,表示在前n个元素中存在一个子集,其和为target,即列表可以被分割成两个和相等的子集,返回true;否则返回false。
所用编程语言:C++;
完整编程代码:↓
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param weights int整型vector * @return bool布尔型 */ bool canPartition(vector<int>& weights) { int n = weights.size(); int sum = 0; for (int i = 0; i < n; i++) { sum += weights[i]; } if (sum % 2 != 0) { return false; } int target = sum / 2; vector<vector<bool>> dp(n, vector<bool>(target + 1, false)); for (int i = 0; i < n; i++) { dp[i][0] = true; } for (int i = 1; i <= target; i++) { if (weights[0] == i) { dp[0][i] = true; } } for (int i = 1; i < n; i++) { for (int j = 1; j <= target; j++) { if (weights[i] > j) { dp[i][j] = dp[i - 1][j]; } else { dp[i][j] = dp[i - 1][j] || dp[i - 1][j - weights[i]]; } } } return dp[n - 1][target]; } };