题目原文:(id=473)
Remember the story of Little Match Girl? By now, you know exactly what matchsticks the little match girl has, please find out a way you can make one square by using up all those matchsticks. You should not break any stick, but you can link them up, and each matchstick must be used exactly one time.
Your input will be several matchsticks the girl has, represented with their stick length. Your output will either be true or false, to represent whether you could make one square using all the matchsticks the little match girl has.
Example 1:
Input: [1,1,2,2,2] Output: true Explanation: You can form a square with length 2, one side of the square came two sticks with length 1.
Example 2:
Input: [3,3,3,3,4] Output: false Explanation: You cannot find a way to form a square with all the matchsticks.
给定若干根火柴的长度,问是否可以用这些火柴刚好拼出正方形,简单来讲就是把一个数列分成和相等的4组数字。一开始考虑过想用分成两组的动态规划的方法,但发现有很大的问题,分成两组那道题还有数字个数相同的限制,而四组数字的个数是随意的。可行的解法只想到直接搜索一种,但是直接枚举的话运算量太大,会超时,所以仍需要适当的剪枝:
- 如果数字的和不为4的倍数则不用搜索
- 对于一个元素,当有2个组的数字和目前相等的话,只用搜索加入其中一组的情况
class Solution {
public:
bool makesquare(vector<int>& nums) {
int n = nums.size();
if (n < 4) return false;
int sol = 0;
for (int i = 0;i < n;i++)
sol += nums[i];
if (sol % 4) return false;
sol /= 4;
vector<int> sum(4, 0);
return dfs(nums, sum, 0, sol);
}
bool dfs(vector<int>& nums, vector<int>& sum, int i, int sol) {
if (i == nums.size()) {
if (sum[0] == sol&&sum[1] == sol&&sum[2] == sol)
return true;
return true;
}
for (int j = 0;j < 4;j++) {
if (sum[j] + nums[i] <= sol) {
if (j>0&&sum[j-1]==sum[j]) continue;
sum[j] += nums[i];
if (dfs(nums, sum, i + 1, sol)) return true;
sum[j] -= nums[i];
}
}
return false;
}
};
本文探讨了如何通过算法判断给定长度的火柴能否拼成一个正方形。利用递归搜索并结合剪枝策略,文章提供了一种有效解决该问题的方法。
591

被折叠的 条评论
为什么被折叠?



