Remember the story of Little Match Girl? By now, you knowexactly what matchsticks the little match girl has, please find out a way youcan make one square by using up all those matchsticks. You should not break anystick, 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 thelittle 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 squarewith all the matchsticks.
Note:
1. The lengthsum of the given matchsticks is in the range of 0 to 10^9.
2. The length ofthe given matchstick array will not exceed 15.
这题简单来说就是一个深度优先遍历,但是不是这么简单,剪枝函数非常复杂,首先是不是4的倍数的减枝,然后是和大于target/4的减枝,最后是最关键的一个减枝,就是当match的某一个值和之前的一个值相等的时候,说明前面那种情况已经被遍历过了,直接跳过这种情况就好了,以后在做树状遍历的题目的时候,要记住如何剪枝,明显不可能的情况可以减去,已经遍历过得情况也可以减去!
以后在做题的时候对数据进行排序可能使用的时间会缩短,以后要记住这一点!这里从大到小排序时间会变短!
Int是21亿而不是2亿,记住
class Solution {
public:
bool dp(vector <int> &match,vector<int> &num, int index,int target)
{
if (index == num.size())
{
return match[0] ==match[1]&& match[1] == match[2]&& match[2] == match[3];
}
for (int i = 0; i < 4; i++)
{
if (match[i] + num[index] >target) continue;
int j = i;
while (--j >= 0)
if (match[j] == match[i])break;
if (j != -1) continue;
match[i] += num[index];
if (dp(match, num, index +1,target))
{
return true;
}
match[i] -= num[index];
}
return false;
}
boolmakesquare(vector<int>& nums) {
if (nums.size() == 0) return false;
int count = 0;
for (int i = 0; i < nums.size(); i++)
count += nums[i];
if (count % 4 != 0) return false;
count = count / 4;
vector<int> match(4, 0);
return dp(match, nums, 0,count);
}
};