Leetcode P473 Java使用DFS解决此问题

Leetcode P473 Java使用DFS解决此问题

idea

首先我们要极端数组所有火柴的边长,在判断下是否符合正方形的需求。

//计算该数组的边长
int sideLength = Arrays.stream(matchsticks).sum();
//判断该边长是否符合正方形边长规范 边长必须是4的倍数
if (sideLength%4 !=0 ){
    return false;
}

接下来我们要排序此数组,因为假如我们的数据为

[1,1,1,1,1,1,1,1,1,1,1,1,1,1,102]

或者

1 1 1 1 2 2 2 2 3 3 3 3 9999

如果我们不进行sort排序对数组我们从下标为0开始,这样我们每一个边长的长度还小于(火柴的边长/4),所以每个火柴就会一直放入火柴,如1,1,1,1,2,2,2....所以我们要从大到小进行遍历,这样就可以大大的减少我们的时间复杂度,从最大的选择可以让我们剩下的边长长度比较小,这样就可以减少回溯的次数了。

​ dfs参数介绍

​ num是火柴数组,index是遍历火柴数组的下标,length是每个边长规定的长度,size是正方形四个边长的数组。

  public boolean dfs(int[] num,int index,int length,int[] size){

在我们进行dfs的时候,如果我们的火柴数组遍历完成,并且每个边相等就代表已经组成了正方形,我们就可以直接返回true,否则就返回false

        if (index == -1){
            if (size[0] == size[1] && size[0] == size[2] && size[0] == size[3])
                return true;
            return false;
        }

​ 接下来我们遍历每个边长,如果当前边长A+当前火柴大于正方形要求的边长长度(火柴的边长/4)那么就跳出当前循环,

​ 如果我们没有再次跳出循环那么就代表我们的我们边长加+当前火柴不大于正方形要求的边长长度,接下来我们就遍历下一个火柴。

​ 当我们进行下一次回溯的时候还会一直看下一个边长是否合法,如果我们所有火柴都调用完毕了,并且size里面的所有边长都相等那么最终就会返回一个true。

                if (dfs(num, index-1, length, size))
                    return true;

如果每一次回溯没有返回true那么我们就将这个火柴从这个边长数组里面拿出来。

​ size[i] -= num[index];

code

class Solution {
    public boolean makesquare(int[] matchsticks) {

        //计算该数组的边长
        int sideLength = Arrays.stream(matchsticks).sum();
        //判断该边长是否符合正方形边长规范 边长必须是4的倍数
        if (sideLength% 4 !=0 ){
            return false;
        }
        Arrays.sort(matchsticks);
        return dfs(matchsticks, matchsticks.length-1, sideLength / 4 ,new int[4]);
    }

    public boolean dfs(int[] num,int index,int length,int[] size){
        if (index == -1){
            if (size[0] == size[1] && size[0] == size[2] && size[0] == size[3])
                return true;
            return false;
        }

        for (int i = 0; i < size.length; i++) {
            if (size[i] + num[index] >length){
                continue;
            }
            size[i] += num[index];
                if (dfs(num, index-1, length, size))
                    return true;
            size[i] -= num[index];
        }

        return false;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哇塞大嘴好帅(DaZuiZui)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值