题目:
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
思路:
- 回溯法
- Collections.swap 这一个工具方法,别写错了。
代码:
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> resultList = new ArrayList<>();
if (nums==null) {
return resultList;
}
//记录下所有要排列的数字
List<Integer> numList = new ArrayList<>();
for (int num: nums) {
numList.add(num);
}
int length = nums.length;
//排列
backTrack( length, resultList, numList, 0);
return resultList;
}
public void backTrack( int length, List<List<Integer>> resultList, List<Integer> numList, int num) {
//如果已经排列完了,就添加到结果集中
if (length == num) {
resultList.add ( new ArrayList<>(numList));
}
// [0,1 ∣ 2,3,4] ,左边的是填过的数,右边的是没有填的数。
// 假设待填的数的下标为 i,那么填完以后我们将第 i 个数和第 num 个数交换,
// 使得在填第 num+1 个数的时候 nums 数组的 [0,num] 部分为已填过的数,[num+1, length−1] 为待填的数。
// 易错点:这里的循环,从 num 开始的。别写错了。
for (int i=num ; i < length; i++) {
//将numList划分成左右两个部分,左边的表示已经填过的数,右边表示待填的数,
//交换,表示 i 已经填过
//Collections.swap 这一个工具方法,别写错了。
Collections.swap ( numList, num, i);
//循环,选择后续数据
backTrack( length, resultList, numList, num+1);
//撤销交换。回溯的时候交换回来即能完成撤销操作
Collections.swap ( numList, num, i );
}
}