题目来源:https://leetcode.cn/problems/matchsticks-to-square/
大致题意:
给一个数组,表示火柴长度,是否可以将火柴分成四条相等的边
思路
题目给定的数组长度不大于 15,所以可以用递归加回溯解题
- 求出数组和,根据数组和求出火柴要组成的边的长度 len
- 递归搜索每根火柴属于不同边的所有可能,如果所有火柴都放入了不同边内,那么表示出现了一种可能的排列,直接返回结果
递归时注意,如果当前新加入火柴使得当前边长度大于 len,那么显然不合理,可以进行剪枝
同时,为了减少搜索量,对火柴进行排序,优先放入大的
代码:
public boolean makesquare(int[] matches) {
int sum = 0;
n = matches.length;
// 求和
for (int i = 0; i < n; i++) {
sum += matches[i];
}
// 不能整除 4,则不能组成四条相等边
if (sum % 4 != 0) {
return false;
}
// 排序
Arrays.sort(matches);
nums = matches;
// 边长
len = sum / 4;
int[] edges = new int[4];
// 倒序放入火柴,优先放大的
return dfs_edges(n - 1, edges);
}
public boolean dfs_edges(int idx, int[] edges) {
// 所有火柴都放入,表示有一种排列,直接返回结果
if (idx < 0) {
return true;
}
// 遍历四条边
for (int i = 0; i < 4; i++) {
// 将当前火柴放入该边
edges[i] += nums[idx];
// 若放入后不大于边长,递归
if (edges[i] <= len && dfs_edges(idx - 1, edges)) {
return true;
}
// 回溯
edges[i] -= nums[idx];
}
return false;
}