• 60. 第k个排列-回溯/数学-困难


    问题描述

    给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。

    按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

    "123"
    "132"
    "213"
    "231"
    "312"
    "321"
    给定 n 和 k,返回第 k 个排列。

    说明:

    给定 n 的范围是 [1, 9]。
    给定 k 的范围是[1,  n!]。
    示例 1:

    输入: n = 3, k = 3
    输出: "213"
    示例 2:

    输入: n = 4, k = 9
    输出: "2314"

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/permutation-sequence

    解答

    /*
    以''开头的的排列有n!个
    以1开头的排列有(n-1)!个,若k<(n-1)!,则排列以1开头,若(n-1)!<k<2*(n-1)!,则排列以2开头....
    以此类推
    ....
    ....
    */
    class Solution{
        public String getPermutation(int n, int k) {
            int[] factorial = new int[]{1,1,2,6,24,120,720,5040,40320};//0-8的阶乘
            StringBuilder res = new StringBuilder();
            boolean[] used = new boolean[n+1];//表示元素用过没有
            for(int i=n-1;i>0;i--){
                int a = k/factorial[i];
                int r = k%factorial[i];
                if(r != 0){
                    a++;
                    k = r;
                }else{
                    k = factorial[i];
                }
                for(int j=1;j<=n;j++){
                    if(!used[j])a--;
                    if(a==0){
                        res.append(j);
                        used[j] = true;
                        break;
                    }
                }
                
            }
            for(int i=1;i<=n;i++)if(!used[i])res.append(i);
            return res.toString();
        }
    }
    /*超时的递归。。
    class Solution {
        Set<Integer> res;
        List<Integer> result;
        int k, n, flag;
        public void dfs(List<Integer> output){
            if(flag!=0)return;
            if(n == res.size()){
                //System.out.println("set:"+output+"idx:"+idx);
                if(--k==0){
                    result = new ArrayList<Integer>(output);
                    flag = 1;
                }
                return;
            }
            for(int i=1;i<=n;i++){
                if(!res.add(i))continue;
                //System.out.println("set:"+output);
                output.add(i);
                dfs(output);
                res.remove(i);
                output.remove(output.size()-1);
            }
        }
    
        public String getPermutation(int n, int k) {
            this.k = k;
            this.n = n;
            flag = 0;
            res = new HashSet<Integer>();
            result = new ArrayList<Integer>();
            dfs(new ArrayList<Integer>());
            StringBuilder sb = new StringBuilder();
            for(int i:result)sb.append(i);
            return sb.toString();
        }
    }
    */
  • 相关阅读:
    正则表达式
    面向对象(访问控制、继承、重写)
    你凌晨1点半会想什么
    10、android学习资源整理
    9、android开发之java.lang.verifyError(转载)
    8、android代码优化技术记录
    6、android 普通日志输出到SD卡
    刷机总结(阿里云os-->android4.2.2)注明:本文不是教程
    忘记树莓派密码怎么办?
    7、android的button如何平铺一张图片?
  • 原文地址:https://www.cnblogs.com/xxxxxiaochuan/p/13758953.html
Copyright © 2020-2023  润新知