60. Permutation Sequence

一、题目

  1、审题

  2、分析

    给两个数字 n 与 k,返回 1-n 所有数字组成的从小到大的全排序的第 k 个数。

二、解答

  1、思路:

    方法一、采用字典序列,返回全部序列后,输出第 k 个。(时间超出,但代码可行)

public String getPermutation(int n, int k) {
        
        Integer num = 0;
        int i = 1;
        while(i <= n) 
            num = num*10 + i++;
        
        List<String> result = new ArrayList<>();
        result.add(num.toString());
        
        helper(result, new StringBuffer().append(num), n-1, n);
        
        for(String s: result)
            System.out.println(s);
        
        System.out.println();
        return result.get(k-1).toString();
    }
    
    private void helper(List<String> result, StringBuffer sb, int index, int len) {
        
        if(index < 0)
            return;
        
        // 1、查找比 index 大的最小的数的 index
        int tmpIndex = -1;
        for(int i = len - 1; i > index; i--) {
            if(sb.charAt(i) > sb.charAt(index)) {
                tmpIndex = i;
                break;
            }
        }
        
        if(tmpIndex != -1) {
            // 交换字符
            char c = sb.charAt(tmpIndex);
            sb.setCharAt(tmpIndex, sb.charAt(index));
            sb.setCharAt(index, c);
            
            // 2、 翻转  index 后面部分
            String s = sb.substring(index+1);
            StringBuffer tmpBuffer = new StringBuffer(s).reverse();

            // add
            sb.delete(index+1, len)
                .append(tmpBuffer.toString());
            
            result.add(sb.toString());
            
            helper(result, sb, len-2, len);
        }
        else {
            helper(result, sb, index - 1, len);
        }
    }

  方法二、采用数学的思维方法: 

    以   n = 4, k = 9 为例:

    ①、总共有 n! = 4!=4 X 3! = 24种排序。可以分为:

      1 和 {2, 3,  4} 

      2 和 {1, 3, 4}

      3 和 {1, 2, 4}

      4 和 {1,2,3}

     的排序。

    ② 对于数组 nums = {1, 2, 3, 4},要确定第一个数字的下标,则 

        K = 8 ;(由于排序的集合开始的下标是0,所以 K = 9 -1 = 8;)

        index = K/ (n-1)! = 8 / (4-1)! = 8/6 = 1; 即确定第一个数字: nums[1] = 2

    ③、由 ① 知,确定了第一个数字 2,即排除了数字 1 开始的所有排序,则剩下的待确定的 K 为:

        K = K - index * (n - 1)! = 8 - 1*(4-1)! = 8 - 6 = 2

      于是: index = K /( n - 2)! = 2 / 2! = 1 ,

      则,对于数组 nums = {1, 3, 4} ,确定了数字 nums[1] = 3;

    ④ 同理:

         K = K - index*(n-2)! = 2 - 1*(4-2)! = 0;

        index = K/(n-3)! = 0 / (n - 3)! = 1 / 1 = 0;

        则对于数组 nums = {1, 4}, 确定了数字 nums[0] = 1;

    ⑤

        K = K - Index * (n - 3)! = 0 - 0 * 1 = 0

        Index = 0 /(n-4)! = 0

        则对于数组 nums = {4},确定了数字 nums[0] = 4

  综上,对于  n = 4, k = 9 的排序为: 2314.

class Solution {
    public String getPermutation(int n, int k) {
        
        
        List<Integer> numbers = new LinkedList<Integer>();
        int[] factorial = new int[n+1];
        StringBuilder sb = new StringBuilder();
        
        // factorial[] = {1, 1, 2, 6, ... , n!}
        int sum = 1;
        factorial[0] = 1;
        for(int i = 1; i <= n; i++) {
            sum *= i;
            factorial[i] = sum; 
        }
        
        // list = {1, 2, 3, 4} , get indices
        for (int i = 1; i <= n; i++) {
            numbers.add(i);
        }
        
        k--;
        
        for(int i = 1; i <= n; i++) {
            int index = k / factorial[n-i];
            sb.append(numbers.remove(index));
            k -= index*factorial[n-i];
        }
        
        return String.valueOf(sb);
    }
}
原文地址:https://www.cnblogs.com/skillking/p/9668588.html