全排列问题
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
回溯算法代码:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>() ;
List<Integer> output = new ArrayList<Integer>() ;
for(int num : nums) {
output.add(num) ;
}
int length = nums.length ;
backtrack(length, output, res, 0) ;
return res;
}
public void backtrack(int length , List<Integer> output , List<List<Integer>> res , int first) {
if(first == length) {
// res.add(output) ;
res.add(new ArrayList<Integer>(output)) ;
}
for (int i = first; i < length; i++) {
Collections.swap(output, first, i);
backtrack(length, output, res, first+1);
Collections.swap(output, first, i);
}
}
}
对于注释的 res.add(output) ; 不能得到正确的结果。
原因是在 Java 中,参数传递是 值传递,对象类型变量在传参的过程中,复制的是变量的地址,这些地址被添加到 res 变量,但实际上指向的是同一块内存地址。
Java基本类型的传参,在方法内部是值拷贝,有一个新的局部变量得到这个值,对这个局部变量的修改不影响原来的参数。
对象类型的传参,传递的是堆上的地址,在方法内部是有一个新的局部变量得到引用地址的拷贝,对该局部变量的操作,影响的是同一块地址,因此原本的参数也会受影响,反之,若修改局部变量的引用地址,则不会对原本的参数产生任何可能的影响。