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