全排列的非递归解法

题目:找到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;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值