• 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);
        }
    }
  • 相关阅读:
    通过模板类简单实现Spark的JobServer
    aggregate 和 treeAggregate 的对比
    IntelliJ Idea 常用快捷键列表
    dataframe 数据统计可视化---spark scala 应用
    用java api读取HDFS文件
    .net Core 简单中间件使用
    .Net Core Ocelot网关使用熔断、限流 二
    .Net Core Ocelot网关使用 一
    Docker 问题处理
    CentOS 创建用户
  • 原文地址:https://www.cnblogs.com/skillking/p/9668588.html
Copyright © 2020-2023  润新知