LeetCode题解-全排列的第k个数字(全排列变体)

来源:互联网 发布:教育大数据平台 编辑:程序博客网 时间:2024/06/06 07:16

题目

/** * LeetCode60 n个数的排列组合找出第k个排列 * 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): "123" "132" "213" "231" "312" "321" Given n and k, return the k th permutation sequence. Note: Given n will be between 1 and 9 inclusive. 时间限制:1秒 */

分析

  1. 乍看是1~N这N个数字的全排列
  2. 变化是,每排好一个就计数,计数到k就输出当前排好的这个数
  3. 注意,如何控制数字按从小到大出现?在算法思维(递归)训练:输出字符串字符的全排列中无需考虑顺序,而且经过实验输出的数字并非完全按从小到大排列。所以需要微调swap函数

代码

public class PermutationSequence {  int count;  String result;  public String getPermutation(int n, int k) {    char[] arr = new char[n];    for (int i = 0; i < n; i++)      arr[i] = (char) ('1' + i);    permutation(arr, 0, k);    return result;  }  private void permutation(char[] arr, int index, int cc) {    //至于什么时候输出,要考虑清楚    //考虑:只有所有位置上的字符都确认即index到达末尾,才算是排好一种情况    if (index == arr.length) {      count++;      // System.out.println(String.valueOf(arr));      if (count == cc)        result = String.valueOf(arr);    }    //现在index之前的字符都已就位,把之后的每个字符都交换到index这个位置    for (int k = index; k < arr.length; k++) {      //尝试交换      swap1(arr, index, k);      //交换之后index这个位置就定好了,接下来的事就是递归去解决index+1位置开始的全排列就好了      permutation(arr, index + 1, cc);      // 前面我们尝试交换,把全排列求出来了,交换时只尝试了一个字符,因此for循环继续之前要换回来,继续尝试交换下一个字符      swap2(arr, index, k);    }  }  private void swap1(char[] arr, int index, int k) {    char tmp = arr[k];    //用插入法不改变后续元素的大小顺序    for (int i = k; i > index; i--) {      arr[i] = arr[i - 1];    }    // arr[k] = arr[index];    arr[index] = tmp;  }  private void swap2(char[] arr, int index, int k) {    char tmp = arr[index];    //用插入法不改变后续元素的大小顺序    for (int i = index; i < k; i++) {      arr[i] = arr[i + 1];    }    arr[k] = tmp;  }  public static void main(String[] args) {    Instant now = Instant.now();    //考虑极限情况消耗的时间:约19毫秒    System.out.println(new PermutationSequence().getPermutation(9,362880));    //结果应该是987654321,362880=9!    System.out.println("毫秒:"+(Instant.now().toEpochMilli()-now.toEpochMilli()));  }}
原创粉丝点击