zoukankan      html  css  js  c++  java
  • 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 (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到n这n个数字,他们的排列组合共有n!个, 把这些数字排列组合的得到的数升序排序,返回其中第k个。


    【思路】

    我们先看上面的例子,对于[1,2,3],如下是他们的组合:

    这些组合数按照大小排序以后我们发现他们分别以1/2/3开头,而且以这些数字开头的排列数目是一样的。在以1开头的排列中,如果不看最高位,那么剩下的部分以2/3开头。而且以它们开头的排列数的数目也是一样的。发现了这个规律以后我们可以做这样的事情:

    首先维持一个列表<1,2,...,n>,列表中的元素升序排列。

    给定一个n和k,我们能计算出总的排列数是n!个,那么k是以第几个数开头的呢?这个数字是(k-1) / (n-1)! + 1,为什么k要减去1呢?比如k=2,那么k/2 + 1= 2,这样会导致如果k能被(n-1)!整除的话,计算出的开始数字增加1,而k减去1的话则会计算出正确的开头数字。

    计算出开始数字是第m个数以后,我们要计算在以第m个数开头的数字中,我们要找第几个数,那么跟新k = (k-1) % (n-1)! + 1。这里的k减去1也是为防止k整除(n-1)!阶乘的时候,k % (n-1)!变为0,而此时k应该等于(n-1)!。

    找到开始数字以后,我们从原始的数字序列中把m删除,继续上面的查找过程。直到列表中所有元素被取出。

    举个例子:n = 3, k = 4:

    1. 列表中元素<1,2,3>

    2. 找到开始数字:m=(k-1) / (n-1)! + 1 = 2. 则以第二元素为开始数字,第二个元素是2.

    3. 在以第二个元素开始的排列中我们找第 k = (k-1) % (n-1)! + 1 = 2个.

    4. 删除第二个元素,列表变为<1,3>,n=2,k=2.

    5. m = 2,列表中第二个元素是3.

    6. k = 1.

    7. 列表变为<1>,n=1,k=1.

    8. 最后一个数字为1.

    9. 返回结果231.

    怎么样?这个过程懂了吗?


    【java代码】

     1 public class Solution {
     2     public String getPermutation(int n, int k) {
     3         List<Integer> list = new LinkedList<Integer>();
     4         int totalnum = 1;
     5         StringBuilder sb = new StringBuilder();
     6         for (int i = 1; i <= n; i++) {
     7             list.add(i);
     8             totalnum *= i;
     9         }
    10 
    11         for (int i = n; i >= 1; i--) {
    12             totalnum /= i;
    13             int rank = (k-1) / totalnum;
    14             k = (k-1) % totalnum + 1;
    15             sb.append(list.get(rank));
    16             list.remove(rank);
    17         }
    18 
    19         return sb.toString();
    20     }
    21 }

  • 相关阅读:
    关于Django
    Django
    如何在六个月掌握一门外语
    基础术语
    机器学习
    2018-01-05 通用型的中文编程语言探讨之一: 高考
    2018-01-04 浅尝The Little Prover一书, 重逢Chez Scheme
    2018-01-03 烂尾工程: Java实现的汇编语言编译器
    2018-01-03 中文编程专栏月报:2017年12月
    2017-12-26 Java关键字的汉化用词探讨
  • 原文地址:https://www.cnblogs.com/liujinhong/p/6007440.html
Copyright © 2011-2022 走看看