Leet.473火柴拼正方形(Matchsticks to Square)
阿新 • • 發佈:2018-12-12
思路:
這道題的相對難點在於求得邊長後 可能有很多條火柴來構成這條邊 而被使用的火柴不能再次使用
若某次使用了某一根火柴 則可能導致另一條本能夠湊成的邊無法湊得 所以需要回溯到上一次選擇
看到這裡
首先想到(只想到)的方法是用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); } }