先粘代码
几个关键地方加了备注应该挺可读的
class Solution {
public void backtrack(int n, ArrayList<Integer> nums, List<List<Integer>> result, int flag) {
if (flag == n)
//溯回次数到达数字长度后,就存进去一组组合数
result.add(new ArrayList<Integer>(nums));
for (int i = flag; i < n; i++) {
Collections.swap(nums, flag, i);
backtrack(n, nums, result, flag + 1);//往前走一步 共走n次
//将交换过的nums传给递归, 然后再换回来
Collections.swap(nums, flag, i);
}
}
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new LinkedList<>();
ArrayList<Integer> carry = new ArrayList<Integer>();
for (int num : nums)
carry.add(num);
int n = nums.length;
backtrack(n, carry, result, 0);
return result;
}
}
使用的回溯的主体思想就是吧存下来的数组长度跟存放每组组合数字的容器和存放容器的容器作为参数传给方法, 方法中将回溯放在循环中,在循环中不断进行数字交换,每一次交换就进行回溯, 下标进一位, 当遍历完全长后就说明一组组和数已被完成, 放入放容器的容器
所以, 每一位数都会引发一次溯回, 它的下一位数又会引发一次溯回, 每一次溯回的结束必然会产生一个组合数, 所以以一个有三个元素的数组作为参数为例, 它的结果有 3x2x1 = 6 种组合
需要注意的地方就是, 循环中每次溯回后要把置换的两个数字再换回来.
做个测试吧
{
int count = 0;
public void backtrack(int n, ArrayList<Integer> nums, List<List<Integer>> result, int flag) {
System.out.println(count++);
if (flag == n)
//溯回次数到达数字长度后,就存进去一组组合数
System.out.println(nums);
result.add(new ArrayList<Integer>(nums));
for (int i = flag; i < n; i++) {
Collections.swap(nums, flag, i);
backtrack(n, nums, result, flag + 1);//往前走一步,共走n次
//将交换过的nums传给递归, 然后再换回来
Collections.swap(nums, flag, i);
}
}
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new LinkedList<>();
ArrayList<Integer> carry = new ArrayList<Integer>();
for (int num : nums)
carry.add(num);
int n = nums.length;
//存入初始数字后进行溯回
backtrack(n, carry, result, 0);
return result;
}
public static void main(String[] args) {
fortysixth_46 test = new fortysixth_46();
int [] nums = {1,2,3};
System.out.println(test.permute(nums));
}
}
输出很清楚
0
1
2
3
[1, 2, 3]
4
5
[1, 3, 2]
6
7
8
[2, 1, 3]
9
10
[2, 3, 1]
11
12
13
[3, 2, 1]
14
15
[3, 1, 2]
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 3, 2], [1, 3, 2], [2, 1, 3], [2, 1, 3], [2, 1, 3], [2, 3, 1], [2, 3, 1], [3, 2, 1], [3, 2, 1], [3, 2, 1], [3, 1, 2], [3, 1, 2]]
Process finished with exit code 0