这个题解使用了回溯算法和分支限界法的思想。首先将火柴根据长度从大到小排序,然后从第一根火柴开始递归搜索。在搜索过程中,通过剪枝策略(如果当前边的长度超过目标长度,就直接返回false)来减少搜索空间。同时使用Counter来统计每种长度火柴的数量,避免重复搜索。搜索过程中,如果四条边都拼接成功,则返回true;如果所有可能的搜索都无法拼成正方形,则返回false。
时间复杂度: O(4^n)
空间复杂度: O(n)
```python
from collections import Counter
class Solution:
def makesquare(self, matchsticks: List[int]) -> bool:
# 计算火柴的总长度,如果不能被4整除,则不能拼成正方形
target = sum(matchsticks)
if target % 4:
return False
target //= 4
# 将火柴根据长度从大到小排序,便于剪枝
matchsticks.sort(reverse=True)
# 使用Counter统计每种长度火柴的数量
cnt = Counter(matchsticks)
# 记录当前每条边的长度
cur = [0] * 4
def dfs(i, length):
# 如果已经拼接了4条边,则成功拼成正方形
if i == 4:
return True
# 如果当前边的长度超过目标长度,则剪枝
if cur[i] > target:
return False
# 如果当前边的长度等于目标长度,则开始拼接下一条边
if cur[i] == target:
return dfs(i + 1, 100000000)
# 尝试拼接不同长度的火柴
for key in cnt:
# 如果当前长度的火柴已经用完或者长度大于上一根火柴,则跳过
if key > length or cnt[key] == 0:
continue
# 将当前火柴拼接到当前边上
cur[i] += key
cnt[key] -= 1
# 递归拼接下一根火柴
if dfs(i, key):
return True
# 如果拼接失败,则回溯
cur[i] -= key
cnt[key] += 1
return False
return dfs(0, 1000000000)
```