https://leetcode-cn.com/problems/matchsticks-to-square/description/

思路:

这道题的相对难点在于求得边长后  可能有很多条火柴来构成这条边 而被使用的火柴不能再次使用

若某次使用了某一根火柴  则可能导致另一条本能够凑成的边无法凑得 所以需要回溯到上一次选择

看到这里

首先想到(只想到)的方法是用DFS来实现

可以说是一个经典的DFS问题类型了

步骤是常见的建立对应的visit数组来对应每条火柴是否使用 尝试每一种选择 若走到死路则回溯到上一节点 visit还原 直到四条边均凑成或者是尝试了所有搭配均失败

这道题由于提到“火柴数组的长度不超过15”

所以可以有一些很好想到的剪枝方法

如果总长度不是4的整数倍/某条边的长度大于理论边长/数组长度为0这样直接返回false

初次进入dfs的边数为4 index对于的是当前尝试使用的是第几根火柴 sumnow是目前在凑的这条边已经使用的火柴的长度和

class Solution 
{
static boolean dfs(int[] nums,boolean[] visit,int bianchang,int index,int sumnow,int bian)
    {
        if(bian==1)//成功条件 
        {
            return true;
        }
        else if(sumnow>bianchang)//当前和大于边长
        {
            return false;
        }
        else if(sumnow==bianchang)//某条边完成 边数-1
        {
            return dfs(nums,visit,bianchang,0,0,bian-1);
        }
        else
        {
            for(int i=index;i<nums.length;i++)
            {
                if(visit[i]==false)
                {
                    visit[i]=true;
                    if(dfs(nums,visit,bianchang,i+1,sumnow+nums[i],bian))
                    {
                        return true;
                    }
                    visit[i]=false;
                }
            }
            return false;
        }
    }
    public boolean makesquare(int[] nums) 
    {
        int totallength=0;
        if(nums.length==0)
        {
            return false;
        }
        for(int i=0;i<nums.length;i++)
        {
            totallength+=nums[i];
        }
        int bianchang=totallength/4;
        if(totallength%4!=0)
        {
            return false;
        }
        for(int i=nums.length-1;i>=0;i--)
        {
            if(nums[i]>bianchang)
            {
                return false;
            }
        }
        boolean visit[]=new boolean[nums.length];
        return dfs(nums,visit,bianchang,0,0,4);
    }    
}

Leet.473火柴拼正方形(Matchsticks to Square)

相关文章: