java解法

主要步骤:

利用阶乘的性质确定排列范围:
对于长度为 n 的排列,前 n-1 位的排列总数为 (n-1)!。
根据 (k-1) / (n-1)! 可以计算出当前排列的起始数字的索引。
递归生成排列:
每次选定一个数字,将其从候选列表中移除。
根据剩余的 k 值,递归处理剩下的数字。
拼接结果:
每次递归选出的数字依次拼接,最终形成完整的排列。

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in); // 创建输入对象
        int n = sc.nextInt(); // 输入 n,表示排列的长度
        int k = sc.nextInt(); // 输入 k,表示需要找的第 k 个排列
        List<Integer> nums = new ArrayList<>(); // 初始化数字列表 [1, 2, ..., n]
        for (int i = 1; i <= n; i++) nums.add(i);
        // 调用函数获取第 k 个排列并输出
        System.out.println(getPermutation(nums, k));
    }

    /**
     * 获取第 k 个排列
     * @param nums 候选数字列表
     * @param k    第 k 个排列(从 1 开始)
     * @return     第 k 个排列的字符串
     */
    public static String getPermutation(List<Integer> nums, int k) {
        // 如果列表为空,返回空字符串(递归终止条件)
        if (nums.size() == 0) return "";
        int n = nums.size(); // 当前列表的长度
        int f = factorial(n - 1); // 计算 (n-1)!,用于确定当前数字的范围
        int index = (k - 1) / f; // 确定当前位数字的索引
        int chosen = nums.remove(index); // 从候选数字列表中移除选择的数字
        k = k - index * f; // 更新 k,处理剩余部分
        // 返回当前选择的数字和剩余数字的排列结果
        return chosen + getPermutation(nums, k);
    }

    /**
     * 计算 n 的阶乘
     * @param n 非负整数
     * @return  n 的阶乘
     */
    public static int factorial(int n) {
        int result = 1; // 初始化结果为 1
        for (int i = 2; i <= n; i++) result *= i; // 从 2 开始累乘到 n
        return result;
    }
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C++解法

更新中
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C解法

更新中
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

JS解法

核心思路:
使用阶乘的性质分割排列范围:
如果第一个数字固定为某值,那么剩下的排列数是 (n-1)!。
利用 k / (n-1)! 可以快速确定当前位的数字是哪一个。
动态更新数字列表:
每次确定一位数字后,将其从候选数字列表中移除。
逐步缩小问题规模:
更新 k 的值为当前范围内的余数,递归处理剩余的排列问题。
边界处理:
当数字列表为空时,递归终止

const readline = require('readline'); // 引入 readline 模块处理标准输入输出
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.on('line', (input) => {
    // 处理输入,第一行为 n,第二行为 k
    if (!global.n) {
        global.n = parseInt(input.trim()); // 读取 n
    } else {
        global.k = parseInt(input.trim()); // 读取 k
        console.log(getKthPermutation(global.n, global.k)); // 输出第 k 个排列
        rl.close(); // 关闭输入流
    }
});

/**
 * 获取第 k 个排列
 * @param {number} n - 数字范围 1 到 n
 * @param {number} k - 第 k 个排列(从 1 开始)
 * @return {string} 返回第 k 个排列的字符串
 */
function getKthPermutation(n, k) {
    let factorials = [1]; // 用于存储阶乘值
    let nums = []; // 候选数字列表

    // 初始化阶乘数组和候选数字列表
    for (let i = 1; i <= n; i++) {
        factorials[i] = factorials[i - 1] * i; // 计算并存储 i 的阶乘
        nums.push(i); // 将数字 i 加入候选数字列表
    }

    k--; // 将 k 转换为从 0 开始的索引
    let result = ''; // 存储最终结果的字符串

    // 从高位到低位依次确定每一位数字
    for (let i = n; i > 0; i--) {
        // 确定当前位数字的索引
        let idx = Math.floor(k / factorials[i - 1]);
        result += nums[idx]; // 将选定的数字添加到结果字符串中
        nums.splice(idx, 1); // 从候选数字列表中移除该数字
        k %= factorials[i - 1]; // 更新 k 的值为余数
    }

    return result; // 返回最终结果
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/145184950"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!