# 0473. Matchsticks to Square ###### tags: `Leetcode` `Medium` `Backtracking` `DFS` Link: https://leetcode.com/problems/matchsticks-to-square/ ## 思路 ### 思路一 DFS 挨个尝试所有的nums元素的组合,是否能恰好构成四段大小相等的sum(这个sum就是nums总数和的四分之一) 本题设计的递归函数: ```dfs(int[] matchsticks, boolean[] used, int edge, int remain, int curr, int start)``` remain表示我们还有几条边没凑.如果凑满四条边,就说明成功. curr表示对于当前的边,我们已经累加了多少数字.如果累加到恰好curSum==sum,那么我们就清零开始DFS下一条边.如果curr>sum,就可以终止当前搜索.如果curr<sum,则当前边还需要尝试搜索更多数字加入进去. used是标记每个数字是否被访问过.因为是整体就是深度搜索+回溯的算法,所以要记得退出时要恢复标记. 另外,一个常用的节省时间的技巧是将nums按照从大到小排序,这样能更容易遇到不合条件的情况,及早剪枝,避免过深的探索。 和[0698. Partition to K Equal Sum Subsets](https://hackmd.io/GIVP1eoSRdaIWt1qFMnDQQ)很像 ### 思路二 Memorization & DFS 我还没仔细看 ## Code ```java= class Solution { public boolean makesquare(int[] matchsticks) { int diameter = 0; for(int stick:matchsticks) diameter += stick; if(diameter%4!=0) return false; boolean[] used = new boolean[matchsticks.length]; Arrays.sort(matchsticks); return dfs(matchsticks, used, diameter/4, 4, 0, matchsticks.length-1); } private boolean dfs(int[] matchsticks, boolean[] used, int edge, int remain, int curr, int start){ if(remain==0) return true; if(curr>edge) return false; if(curr==edge) return dfs(matchsticks, used, edge, remain-1, 0, matchsticks.length-1); for(int i=start; i>=0; i--){ if(used[i]) continue; used[i] = true; if(dfs(matchsticks, used, edge, remain, curr+matchsticks[i], i-1)) return true; used[i] = false; } return false; } } ```