[LeetCode]60. Permutation Sequence

题目描述:

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

By listing and labeling all of the permutations in order, we get the following sequence 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.

  • Given k will be between 1 and n! inclusive.

Example 1:

Input: n = 3, k = 3
Output: "213"

Example 2:

Input: n = 4, k = 9
Output: "2314"

题解

该题其实本质上是一个找规律的题,我们可以试图列出n=4是的全排列,从中一探究竟

  1. 1    2    3    4
  2.   2    4    3
  3.   3    2    4
  4. 1    3    4    2
  5.   4    2    3
  6.   4    3    2
  7. 2    1    3    4  
  8. 2    1    4    3
  9. 2    3    1    4
  10. 2    3    4    1 
  11. 2    4    1    3
  12. 2    4    3    1
  13. 3    1    2    4
  14. 3    1    4    2
  15.   2    1    4
  16. 3    2    4    1
  17.   4    1    2
  18. 3    4    2    1

从上面的排列可以看出:

第一位每个数字出现次数为6次=3!=(n-1)!

第一位数字确定之后,第二位中剩下的每个数字出现的次数为2次=2!=(n-2)!

第一二位数字确定之后,第三位中剩下的每个数字出现的次数为1次=1!=(n-3)!

第一二三位数字确定之后,第四位中剩下的每个数字出现的次数为1次=0!=(n-4)!

假设将1-->n存储到一个数组中,那么k-th排列的

第一位为数组元素中的第(k/{(n-1)!})位置,取出该元素之后应该将该元素从数组中删除,然后对k应该更新为k%(n-1)!

第二位为数组元素中的第 (k/{(n-2)!})位置,取出对应元素之后应该将该元素从数组中删除,然后将k更新为k%(n-2)!

...

循环直到第n位为止

在循环中多次用到阶乘,因此我们可以将0-(n-1)的阶乘提前算出存储到一个数组中

为了便于操作(存在多次(n-1)元素的删除操作)我们将使用一个ArrayList来进行存储参与排列的数

具体的代码如下

    public String getPermutation(int n, int k) {
        String res="";
        //初始化阶段
        List<Integer> numbers = new ArrayList<>();
        int[] factorial = new int[n];
        for(int i=1;i<=n;i++) {
        	//将排列用到的数字先存到一个list中
        	numbers.add(i);
        	//将阶乘先存到数组里
        	if(i==1) {
        		factorial[i-1]=i;
        	}else {
        		factorial[i-1]=(i-1)*factorial[i-2];
        	}
        }
        --k;
        //核心部分
        for(int i=1;i<=n;i++) {
        	int index = k/factorial[n-i];
        	res+=numbers.get(index);
        	numbers.remove(index);
        	k%=factorial[n-i];
        }
        return res;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值