解题思路:原本打算暴力求解法解决这个问题,发现有LTE问题,后面看了答案发现,这是经典的背包问题,需要专门找个时间对背包问题仔细分析,留着回过头来分析
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<math.h>
using namespace std;
// 方法一:暴力求解法,TLE问题
//class Solution {
//public:
// bool canPartition(vector<int>& nums) {
// if (nums.size() < 2) return false;
// int sum = 0, halfSum = 0;
// for (int i = 0; i < nums.size(); i++) {
// sum += nums[i];
// }
// if (sum & 1) return false;
// halfSum = sum / 2;
// sort(nums.begin(), nums.end());
// bool canPart = false;
// for (int i = nums.size() - 1; i >= nums.size() / 2; i--) {
// if (canPart) break;
// if (nums[i] > halfSum) continue;
// if (nums[i] == halfSum) {
// canPart = true;
// break;
// }
// recursionCanPartition(halfSum - nums[i], nums, i, canPart);
// }
// return canPart;
// }
//
// void recursionCanPartition(int leftValue, vector<int> nums, int index, bool& canPart) {
// for (int i = index - 1; i >= 0; i--) {
// if (canPart) return;
// if (nums[i] > leftValue) continue;
// if (nums[i] == leftValue) {
// canPart = true;
// return;
// }
// recursionCanPartition(leftValue - nums[i], nums, i, canPart);
// }
// }
//};
// 方法二: 利用二叉树层序遍历的思路,借用队列, 时间复杂度是2的n次方,也是LTE问题
class Solution {
public:
bool canPartition(vector<int>& nums) {
if (nums.size() < 2) return false;
int sum = 0, halfSum = 0;
for (int i = 0; i < nums.size(); i++) {
sum += nums[i];
}
if (sum & 1) return false;
sort(nums.begin(), nums.end());
删除成对出现的重复元素
//for (int i = 1; i > 0 && i < nums.size(); i++) {
// if (nums[i] == nums[i - 1]) {
// nums.erase(nums.begin() + 1);
// nums.erase(nums.begin() + i - 1);
// i = i - 2;
// }
//}
if (nums.size() == 0) {
return true;
}
queue<int> queue;
queue.push(nums[0]);
for (int i = 1; i < nums.size(); i++) {
for (int j = 0; j < pow(2, i - 1); j++) {
queue.push(queue.front() + nums[i]);
queue.push(queue.front() - nums[i]);
queue.pop();
}
}
while (!queue.empty()) {
if (queue.front() == 0) return true;
queue.pop();
}
return false;
}
};