题目
你将得到一个整数数组 matchsticks ,其中 matchsticks[i] 是第 i 个火柴棒的长度。你要用 所有的火柴棍 拼成一个正方形。你 不能折断 任何一根火柴棒,但你可以把它们连在一起,而且每根火柴棒必须 使用一次 。
如果你能使这个正方形,则返回 true ,否则返回 false 。
示例1:
输入: matchsticks = [1,1,2,2,2]
输出: true
解释: 能拼成一个边长为2的正方形,每边两根火柴。
示例 2:
输入: matchsticks = [3,3,3,3,4]
输出: false
解释: 不能用所有火柴拼成一个正方形。
提示:
1 <= matchsticks.length <= 15
1 <= matchsticks[i] <= 108
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/matchsticks-to-square
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析
看到规模我们可以直接想暴力的方法,n<=15,这时我们直接想最暴力的方法,我们可以将一个火柴尝试放在四个边,然后以此类推,一个火柴四种选择,最大15个火柴就是4的15次方,2的30次方,10的9次方,显然会超时,这时我们再去判断如何剪枝
1.如果给定的火柴小于4那一定不行
2.如果给定的火柴总长度不能整除4一定不行
3.一个边的最大长度应该是总长的四分之一,超出四分之一一定不行
优化
1.我们可以将给定的数组进行排序,大的放在前面
因为小的数字组合的可能更多,大的组合的情况少,这样回溯就会变少
经过这几部优化也差不多了,如果还觉得不行可以加记忆化
这道题可以把它想象成向四个桶里放火柴,遍历每个桶放该火柴行还是不行,如果不行的话就回溯遍历其他桶,直到遍历完所有桶,如果都不行,那就拼不成一个正方形
代码部分
1.初始化
首先判断如果给定的数组里火柴的数量少于四个直接返回false,初始化一个sum计算火柴的总长度,判断总长度如果不能整除4直接返回false,然后再来个从大到小排序
if(matchsticks.size()<4)
return false;
int sum=0;
for(int i=0;i<matchsticks.size();i++)
sum+=matchsticks[i];
if(sum%4!=0)
return false;
sort(matchsticks