class Solution {
int ave = 0;
int num = 4;
public boolean makesquare(int[] matchsticks) {
int sum = 0;
for (int matchstick : matchsticks) {
sum += matchstick;
}
ave = sum / 4;
if (ave * 4 != sum) {
return false;
}
Arrays.sort(matchsticks);
if(matchsticks[matchsticks.length-1]>ave){
return false;
}
return f(matchsticks,matchsticks.length-1,ave);
}
private boolean f(int[] matchsticks, int i, int x) {
if(x == 0){
return true;
}
if(i < 0 && x != 0){
return false;
}
if(matchsticks[i] == 0){
if(i-1 < 0){
return false;
}
return f(matchsticks,i-1,x);
}
int buf = 0 ;
for (int j = i; j >= 0; j--) {
if(matchsticks[j] > x){
continue;
}
//取这个值
buf = matchsticks[j];
matchsticks[j] = 0;
boolean f = f(matchsticks, j - 1, x - buf);
if(f){
num--;
if(num <= 0){
return true;
}
boolean f1 = f(matchsticks, matchsticks.length - 1, ave);
if(f1){
return true;
}
num++;
}
matchsticks[j] = buf;
}
return false;
}
}

官网最佳实践 比我写的简洁,多了两步优化,时间关系,没有自己写过,直接复制了
class Solution {
public boolean makesquare(int[] matchsticks) {
int sum = 0;
for(int i : matchsticks){
sum += i;
}
//剪枝
if(sum % 4 != 0) return false;
int target = sum / 4;
//通过排序达到将桶更快装满得目的
Arrays.sort(matchsticks);
//如果排序结束后,最后一个数大于target,说明肯定不成立,因为至少会有一组得和大于target,直接返回false;
if(matchsticks[matchsticks.length - 1] > target) return false;
//定义used数组用于记录当前得matchstick是否是使用过得
boolean[] used = new boolean[matchsticks.length];
return dfs(matchsticks,target,used,0,4,matchsticks.length - 1);
}
public boolean dfs(int[] matchsticks,int target,boolean[] used,int curSum,int k,int begin){
//剪枝,如果前面得都分配好了,最后一组就不用分配了,自然是满足得。
if(k == 1) return true;
//填好了一个桶之后进行下一个桶得装填,总共要放四个桶,桶对应每一条边
if(target == curSum) return dfs(matchsticks,target,used,0,k - 1,matchsticks.length - 1);
for(int i = begin;i>=0;i--){
//如果这个数用过了,直接跳过
if(used[i]) continue;
//大于得话直接跳过,做到剪枝
if(curSum + matchsticks[i] > target) continue;
used[i] = true;
//继续放数字进桶里
if(dfs(matchsticks,target,used,curSum + matchsticks[i],k,i - 1)){
return true;
}
//回溯
used[i] = false;
//继续剪枝,相同得值第一个放进去不行后面得肯定也不行
while(i>0 && matchsticks[i] == matchsticks[i - 1]){
i--;
}
}
return false;
}
}
