版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
思路:很容易想到dfs+回溯,定义一个同给定数组长的度的数组来记录每次递归时该下标的值有无没记录。这里用数组和stack都一样,用数组只需每次当pos到n,转一次arrayslist就行 。还可以用stl中的next_permutation的原理,定义两个指针,从右往左,找到第一个前面的数小于后面的数记为n,再从右往左一次找到第一个比n位置数大数记为m,交换m n 两数,颠倒m位置后的排序
next_permutation:
void nextPermutation(int nums) {
for(int i = nums.length-1; i >= 0; i++){
if(nums[i] > nums[i-1]){
n = i-1;
break;
}
}
for(int i = nums.length-1; i >= 0; i++){
if(nums[i] > nums[n]){
m = i;
break;
}
}
int temp = nums[n];
nums[n] = nums[m];
nums[m] = temp;
Arrays.sort(nums,m+1,nums.length);
}
题解:
class Solution {
int n;
Stack<Integer> path;
List<List<Integer>> res;
boolean[] state;
public List<List<Integer>> permute(int[] nums) {
n = nums.length;
if(n <= 0) return res;
state = new boolean[n];
path = new Stack();
res = new LinkedList();
dfs(nums, 0);
return res;
}
public void dfs(int[] nums, int pos){
if(pos == n){
res.add(new LinkedList(path));
return ;
}
for(int i = 0; i < n; i++){
if(!state[i]){
// 保存现场
state[i] = true;
path.push(nums[i]);
dfs(nums, pos + 1);
// 恢复现场
path.pop();
state[i] = false;
}
}
}
}