就暴力递归 + 回溯(省空间)
每次递归, 从小到大(所以一上来要对num进行排序)遍历待选的数,
选到的数从remain中删除,并插入perm中。
O(n!) O(n!)
import java.util.*;
public class Solution {
ArrayList<ArrayList<Integer>> ans = new ArrayList<>();
public ArrayList<ArrayList<Integer>> permute(int[] num) {
// sort just to insure output in alphabet order
Arrays.sort(num);
// copy sorted nums to remain
ArrayList<Integer> remain = new ArrayList<>();
for (int n : num) remain.add(n);
permuteRec(remain, new ArrayList<>());
return ans;
}
public void permuteRec(ArrayList<Integer> remain, ArrayList<Integer> perm) {
// base case, i.e. no remaining elem
if (remain.isEmpty()) {
// 存答案时必须存copy, 不然之后的回溯会overwrite存入的答案。
ans.add(new ArrayList<>(perm));
return;
}
for (int i = 0; i < remain.size(); i++) {
Integer a = remain.remove(i);
perm.add(a);
permuteRec(remain, perm);
// 复原 (a.k.a 回溯)
remain.add(i, a);
perm.remove(perm.size()-1);
}
}
}