Permutations

求一个数组的全排列。

遇到的问题:

1.忘记了字典序排列的定义;
2.思考时间过长;
3.没有及时找到全排列和字典序之间的关系;

想到的解题思路:

1.用字典序找到下一个排序;
2.全排序共有n!种组合,找够停止循环;

代码如下:

class Solution {
    public List> permute(int[] nums) {
        List> ans = new ArrayList<>();
// 如果数组长度是零直接返回
        if(nums.length == 0)
            return ans;
//求数组全排列
        int n = nums.length;
        int sum = 1;
        for(int i=2;i<=n;i++)
            sum *=i;
        for(;sum>0;sum--){
            ans.add(nextPermutation(nums));
        }
        return ans;
    }
//按照字典序求下一个排列
    public List nextPermutation(int[] nums){
        int flag = 0;
        int j = 0;
//从头开始找到比右边数字的小的数的最大序号j
        for(int i=0;i j)
                    j = flag;
            }
        }
        List l = new ArrayList<>();
        int k = 0;
//从j开始,找到比j大的最小的数的序号k
        for(int i=j+1;inums[j])
                k = i;
            else
                break;
            }
        if(k == 0)
            Arrays.sort(nums);
        else{
//交换j,k
            int tmp = nums[j];
            nums[j] = nums[k];
            nums[k] = tmp;
//倒置j+1到n-1之间的数得到字典序的下一个排列
            for(int i=1;i<=(nums.length-j-1)/2;i++){
                tmp = nums[nums.length-i];
                nums[nums.length-i] = nums[j+i];
                nums[j+i] = tmp;
            }
        }
        for(int i=0;i

附加内容:

1.字典序的概念:

设P是1~n的一个全排列

1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即 j=max{i|pii+1}

2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk,即 k=max{i|pi>pj}(右边的数从右至左是递增的,因此k是所有大于pj的数字中序号最大者)

3)对换pj,pk

4)再将pj+1......pk-1pkpk+1......pn倒转得到排列p'=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个排列。

2.全排列概念:

从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
公式:全排列数f(n)=n!(定义0!=1)

你可能感兴趣的:(Permutations)