题目:找到12345的全排列所有结果。
思路:所有的全排列组成的数字中,12345最小,54321最大。算法本质是找到给定数字m1的下一个数字m2,m2是所有全排列组成的数字集合中大于m1的数字组成的集合的最小值。比如12345下一位是12354。
1,从右往左找到非升序的第一位数
例如12543中543是升序,2就是要找的数字。
2,找到升序部分最小的数字,交换
第一步中的543中最小值为3,2和3交换,得到13542。
3,原来的升序部分进行排序
13542中对542进行排序后是245,最终得到13245。
代码
public class Solution {
/*
* @param nums: A list of integers.
* @return: A list of permutations.
*/
public List<List<Integer>> permute(int[] nums) {
// write your code here
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<>();
if(nums.length == 0){
res.add(new ArrayList<>());
return res;
}
List<Integer> list = new ArrayList<>();
List<Integer> temp = new ArrayList<>();
for(int i : nums){
list.add(i);
}
res.add(list);
while((temp = getNext(list)) != null){
res.add(temp);
list = temp;
}
return res;
}
public List<Integer> getNext(List<Integer> list){
if(list.size() == 0) return new ArrayList<Integer>();
int len = list.size();
int[] nums = new int[len];
for (int j = 0; j < len; j++){
nums[j] = list.get(j);
}
int i = 0;
for(i = len - 1; i > 0; i--){
if(nums[i] > nums[i - 1]){
break;
}
}
if(i == 0) return null;
int minIndex = i;
for(int j = i + 1; j < len; j++){
if(nums[j] > nums[i - 1] && nums[minIndex] > nums[j]) minIndex = j;
}
int temp = nums[i - 1];
nums[i - 1] = nums[minIndex];
nums[minIndex] = temp;
Arrays.sort(nums, i, len);
List<Integer> res = new ArrayList<>(len);
for(int j : nums){
res.add(j);
}
return res;
}
}