其他分享
首页 > 其他分享> > leetcode 每日一题 473. 火柴拼正方形

leetcode 每日一题 473. 火柴拼正方形

作者:互联网

leetcode 每日一题  473. 火柴拼正方形

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;
    }
}

 

标签:used,return,target,正方形,int,matchsticks,473,false,leetcode
来源: https://www.cnblogs.com/yexuba/p/16336506.html