一个没有重复数字的序列,返回其所有可能的全排列。
比如:
输入: [1,2,3]
返回:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
这个题目,人脑是很容易想出来解决办法,用代码来实现,就要用到回溯算法,递归来实现。
这里用深度优先遍历,比如以1开头的,第2个位置,可选择的只有2或3,第3个位置,只剩下一个,不用选了。
public List<List<Integer>> permute(int[] nums) {
int len = nums.length;
List<List<Integer>> res = new ArrayList<>();
if(len == 0){
return res;
}
Deque<Integer> path = new ArrayDeque<>(); // 遍历的深度
boolean[] used = new boolean[len]; // 记录在某个序列中,元素是否被使用过。
dfs(nums,len, 0, path, used, res);
return res;
}
private void dfs(int[] nums, int len, int depth,Deque<Integer> path, boolean[] used, List<List<Integer>> res){
if(depth == len){
res.add(new ArrayList<>(path)); // 将path复制一份。path后面有remove操作,不能直接使用
return;
}
for(int i = 0; i < len; i++){
// 使用过的元素,直接路过。比如前文说的,第2个位置,只有2和3,因为1已经用过了
if(used[i]){
continue;
}
// 如前面的例子,第2个位置,假如放的是2,再次调用dfs,path中3会被放入。再调用一次,就进入return了。
path.addLast(nums[i]);
used[i] = true;
dfs(nums,len, depth + 1, path, used, res);
path.removeLast(); // 恢复所有的操作,
used[i] = false;
}
}
确实不好理解,但一旦想明白了,就不觉得难了。