题目描述:
Given a collection of distinct integers, return all possible permutations.
Example:
Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
思路1:
https://blog.csdn.net/orangefly0214/article/details/84558422和字符串排列的思路是一样的,这里,我们仍然采用递归的方法。固定住第一个字符,求剩余部分的全排列。
step1:把数组分为两部分,一部分是数组的第一个元素,另一部分是第一个元素以后的所有元素(有阴影背景的区域)。
step2:接下来求阴影部分数字的排列,拿第一个字符和后面的字符逐个交换。
参考下面这幅图:
实现1(递归):
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> ret=new ArrayList<>();
if(nums==null||nums.length==0){
return ret;
}
fun(nums,0,ret);
return ret;
}
private void fun(int[] nums, int i, List<List<Integer>> ret) {
if(i==nums.length-1){
if(!ret.contains(nums)){
ArrayList<Integer> sub=new ArrayList<>();
for(Integer ele:nums){
sub.add(ele);
}
ret.add(sub);
return;
}
}else{
for(int j=i;j<nums.length;j++){
swap(nums,i,j);
fun(nums,i+1,ret);
swap(nums,i,j);
}
}
}
private void swap(int[] nums, int i, int j) {
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
实现2:字典序排序
字典序排序的方法:
1.从该序列的最右端开始向左找出第一个比与自己相邻的右边数小的数,记其下标为j,即j = max{i|Pi<Pi+1}.
2.找出Pj右边比Pj大的最小数Pk.
3.交换Pj,Pk.此时序列变为 P’: P1 P2 P3...Pj-1 Pk Pj+1...Pk-1 Pj Pk+1...Pn
4.将Pj+1...Pn 倒转,即得到此序列的后一个序列 P”: P1 P2 P3...Pj-1 Pn...Pk+1 Pj Pk-1...Pj+1④
总结概括为以下四步:
①从右往左,找到第一个比后一个数小的数,找到的这个数的下标记为index。
②从右往左,找到第一个比找到数大的数,下标记为j.
③交换index和j.
④对index+1以后的数进行一个整体的reverse。
循环退出的条件:j==0时,返回最终的结果集。
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> ret=new ArrayList<>();
if(nums==null||nums.length==0){
return ret;
}
if(nums.length==1){
ArrayList<Integer> temp=new ArrayList<>();
temp.add(nums[0]);
ret.add(temp);
return ret;
}
Arrays.sort(nums);
while(true){
ArrayList<Integer> sub=new ArrayList<Integer>();
for(Integer ele:nums){
sub.add(ele);
}
ret.add(new ArrayList<>(sub));
int j;
int index=0;
for(j=nums.length-2;j>=0;j--){
if(nums[j]<nums[j+1]){
index=j;
break;
}else if(j==0){
return ret;
}
}
for(j=nums.length-1;j>=0;j--){
if(nums[j]>nums[index]){
break;
}
}
swap(nums,index,j);
reverse(nums,index+1,nums.length-1);
}
}
private void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
private void reverse(int[] nums,int i,int j){
while(i<j){
swap(nums,i,j);
i++;
j--;
}
}
}