---
# System prepended metadata

title: 0473. Matchsticks to Square
tags: [Leetcode, DFS, Medium, Backtracking]

---

# 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;
    }
}
```