题目
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
思路一
这题需要借助递推的思路,递推的过程如下:
1,2,3
我们依次加入,初始状态为[[1]];- 现在放入
2
,对于[1]
,可以放在1
的左边,也可以放在1
的右边,因此我们得到[[1,2],[2,1]]
; - 现在放入
3
,对于[1,2]
,3
有三个位置可以放入,得到[1,2,3],[1,3,2],[3,1,2]
,同样对于[2,1]
,3
也有三个位置可以放入,最终会得到[[1,2,3],[1,3,2],[3,1,2],[2,1,3],[2,3,1],[3,2,1]]
;
时间复杂度: O ( n × n ! ) O(n\times n!) O(n×n!),空间上额外辅助空间为 O ( 1 ) O(1) O(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>> ans = new ArrayList<>();
if (nums.length > 0)
ans.add(Collections.singletonList(nums[0]));
for (int i=1; i<nums.length; i++) {
int size = ans.size();
for (int j=0; j<size; j++){
List<Integer> t = ans.get(j);
for (int k=0; k<=t.size(); k++){
List<Integer> temp = new ArrayList<>(t);
temp.add(k, nums[i]);
ans.add(temp);
}
}
while (size-- > 0) ans.remove(0);
}
return ans;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = {1,2,3};
System.out.println(solution.permute(nums));
}
}
思路二
dfs,不断地交换数组元素,每一层递归,我们确定一个元素排到当前首位,再进行下一层递归,直到最后一个元素位置也确定,递归结束;
代码二
import java.util.*;
public class Solution {
public void swap(int[] nums, int i, int j){
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
public void dfs(List<List<Integer>> listList, int[] nums, int idx){
if (idx == nums.length-1){
List<Integer> t = new ArrayList<>();
for (int num : nums) t.add(num);
listList.add(t);
}
for (int i=idx; i<nums.length; i++){
swap(nums, idx, i);
dfs(listList, nums, idx+1);
swap(nums, idx, i);
}
}
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
dfs(ans, nums, 0);
return ans;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = {1,2,3};
System.out.println(solution.permute(nums));
}
}
思路三
把数组的每个元素看作图的节点,并且这个图是一个全连接图,那么遍历图的所有路径就对应所有的全排列,具体见代码:
代码
import java.util.*;
public class Solution {
List<List<Integer>> ans;
public void dfs(List<Integer> path, boolean[] visited, int[] nums){
if (path.size() == nums.length) {
ans.add(new ArrayList<>(path));
return;
}
for (int i=0; i<nums.length; i++){
if (visited[i])
continue;
visited[i] = true;
path.add(nums[i]);
dfs(path, visited, nums);
visited[i] = false;
path.remove(path.size()-1);
}
}
public List<List<Integer>> permute(int[] nums) {
ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
boolean[] visited = new boolean[nums.length];
dfs(path, visited, nums);
return ans;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = {1,2,3};
System.out.println(solution.permute(nums));
}
}