题目:
解题思路
乍一看,以为是一个集合子集问题,直接使用回溯暴力检索,但是仔细一想并非如此。上网寻找资料发现并没有相关的算法,所以只能自己绞尽脑汁自己想一个了。作为一个算法渣渣,这个着实有点为难我了。
回到正题:这个题目应该使用深度搜索,对每个元素进行分析,这个元素要么放到已知的划分集合里面,要么自己创建一个新的划分放进去。
注意:因为划分不能为空,所以一定要首先把set第一个元素作为一个已知划分放到结果数组里面。
代码
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Stack;
import java.util.Spliterator.OfPrimitive;
class Solution {
public static void main(String[] args) {
// 制造数据
int n = 4;
char[] set = new char[] { 'a', 'b', 'c', 'd' };
Solution solution = new Solution();
// 思路,对于每个元素,这个元素要么在之前的一个集合,要么自己新建立一个集合放入
solution.solve(set, n);
}
ArrayList<LinkedList<Character>> res = new ArrayList<>();
public void solve(char[] set, int n) {
// 把第一个元素做为一个划分放到结果数组里
LinkedList<Character> tmp = new LinkedList<>();
tmp.add(set[0]);
res.add(tmp);
dfs(1, 1, n, set);
}
// x是第x个字母(下标从0开始),m是已知有m个划分集合,n是set的大小
public void dfs(int x, int m, int n, char[] set) {
if (x == n) {
// 输出
System.out.println(res);
return;
}
// 自建一个集合
LinkedList<Character> tmp = new LinkedList<>();
tmp.add(set[x]);
res.add(tmp);
dfs(x + 1, m + 1, n, set);
// 拿走这个独立集合
res.remove(res.size() - 1);
// 放到已知划分集合里面
for (int i = 0; i < m; i++) {
// 把x位置的元素放到第i个集合上
LinkedList tmp2 = res.get(i);
tmp2.add(set[x]);
dfs(x + 1, m, n, set);
// 拿走
tmp2.removeLast();
}
}
}