华为OD 第k个排序

题目描述

给定参数 n,从 1 到 n 会有 n 个整数:1,2,3,…,n, 这 n 个数字共有 n! 种排列。

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

  • “123”
  • “132”
  • “213”
  • “231”
  • “312”
  • “321”

给定 n 和 k,返回第 k 个排列。

输入描述

输入两行,第一行为 n,第二行为 k,

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

输出描述

输出排在第 k 位置的数字。

用例1

输入

3
3

输出

213

说明

3的排列有123,132,213…,那么第三位置就是213

用例2

输入

2
2

输出

21

说明

2的排列有12,21,那么第二位置的为21。

import java.util.Scanner;
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {

    static Map<Integer, Integer> map = new HashMap<Integer, Integer>();

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int k = in.nextInt();
        func(9);
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 1; i <= n; i++) {
            list.add(i);
        }
        StringBuilder builder = new StringBuilder();
        while (k % map.get(n - 1) != 0) {
            int num = k / map.get(n - 1);
            builder.append(list.get(num));
            list.remove(num);
            k = k % map.get(n - 1);
            n = n - 1;
        }
        int num = k / map.get(n - 1);
        builder.append(list.get(num - 1));
        list.remove(num - 1);
        if (list.size() > 0) {
            list.sort((a,b) -> b.compareTo(a));
            list.forEach(e-> {
                builder.append(e);
            });
        }
        System.out.println(builder.toString());

    }

    public static int func(int n) {
        if (n == 1) {
            map.put(1, 1);
            return 1;
        }
        if (map.get(n) != null) {
            return map.get(n);
        }
        map.put(n, n * func(n - 1));
        return n * func(n - 1);
    }
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值