145.Permutation Sequence(求第k(1,2,3..n)个排列)

The set [1,2,3,…,n] contains a total ofn! unique permutations.

By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

Given n and k, return the kth permutation sequence.

Note: Given n will be between 1 and 9 inclusive.

注意:这个题目真的是自己写的,要相信自己,自信~

 
     计算1,2,3,...n共n个数字的全排列中的第k个,方法一可以先计算出这n!个全排列,然后取出第k个。
    但是也可以通过发现规律,找第k个排列的时候,没有必要对其前面所有的进行排列,只需要找其各个位置上的数字即可。
    首先用数组fac[i]来表示i的阶乘,把待放到最后结果中的数字按照顺序存放到list中,count表示还剩下的数字个数。
    对于所求的第k(k从1开始)个排列,
    Step0: 首先判断count是否为1,位1则结束循环,跳到Step7;
    Step1: 可以用(k-1)/fac[count-1]计算目前应该加入到结果中的数字在list中的下标为num。
    Step2: 然后更新k的值为(k-1)%fac[count-1]+1。
    Step3: count--;
    Step4: 把list.get(num)合并到结果中;
    Step5: 把list中下标为num的数字从list中移除。
    Step6: 继续循环;
    Step7: 把剩下的最后一个数字合并到最后结果中;
    Step8: 返回最终的结果。

    比如对于1,2,3,4排列的第18个序列。

    用list保存1  2  3 4。初始化count = 4.

    fac[5] = {1,1,2,6,24}

    第一次进入循环:num = (18-1)/6 = 2;

    所以第一次合并到结果中的数字为list.get(2) = 3;然后把下标为2的元素移除list,并且count--。更新k的值为6,

    然后接着继续循环得到了合并到结果中数字为4,2,直到list中只剩下一个数字,1合并到结果中,这样我们就得到了最后的结果为3421.

public String getPermutation(int n, int k)
        {
            if(n == 0){
                return "";
            }
            /*fac[i]存放的是i的阶乘*/
            int[] fac = new int[n+1];
            factorial(fac,n+1);
            /*list中存放待放到结果中的数字*/
            List<Integer> list = new ArrayList<Integer>();
            for (int i = 1; i <= n;i++)
            {
                list.add(i);
            }
            int count = list.size();//count表示剩下待加入到结果中的数字个数
            /*循环计算把该放入到结果中的数字先存到sb中*/
            StringBuilder sb = new StringBuilder();
            while(count!=1){
                int num = (k-1) / fac[count-1];
                k = (k-1) % fac[count-1]+1;
                sb.append(list.get(num));
                list.remove(num);
                count--;
            }
            sb.append(list.get(0));
            return sb.toString();
        }



        /*计算小于等于n的所有整数的阶乘*/
        public void factorial(int[] fac,int n){
            fac[0] = 1;
            for (int i = 1; i < n;i++ )
            {
                fac[i] = fac[i - 1] * i;
            }
        }






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值