当前位置: 首页 > news >正文

力扣第 60 题 “第 k 个排列”

题目描述

给定整数 nk,返回由 1n 组成的排列中第 k 个排列。

  • 所有排列按字典序排列。
  • 1 ≤ n ≤ 91 ≤ k ≤ n!

解题思路

要快速找到第 k 个排列,可以利用数学方法而不是生成所有排列:

1. 知识点:阶乘与字典序
  • 对于给定的 n,共有 n! 种排列。
  • 每个数字作为排列的起点时,其后续排列数为 (n-1)!
  • 利用这一规律,可以逐步确定排列的每一位。
2. 数学推导
  1. 确定第 1 位

    • k(n-1)! 为单位划分。
    • 第一个数字是 (k-1)/(n-1)! + 1
    • 更新 k = k % (n-1)!
  2. 重复确定后续数字

    • 每次缩小范围,使用相同的逻辑继续计算。
  3. 数字选择

    • 使用一个列表存储可选的数字,每次选中一个后移除。
3. 算法步骤
  1. 计算阶乘数组,用于快速获取 (n-1)!
  2. 使用数字列表维护当前可以使用的数字。
  3. 根据 k 确定每一位数字。

C 语言代码实现

以下是完整的 C 语言实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 主函数:获取第 k 个排列
char* getPermutation(int n, int k) {// 计算阶乘数组int factorial[n];factorial[0] = 1;for (int i = 1; i < n; i++) {factorial[i] = factorial[i - 1] * i;}// 可选数字列表int numbers[n];for (int i = 0; i < n; i++) {numbers[i] = i + 1; // 初始为 [1, 2, ..., n]}// 分配结果字符串char* result = (char*)malloc((n + 1) * sizeof(char));result[n] = '\0'; // 末尾加结束符// 调整为从 0 开始的索引k--;// 构造排列for (int i = 0; i < n; i++) {int index = k / factorial[n - 1 - i]; // 当前数字的索引result[i] = numbers[index] + '0';    // 转为字符// 删除已选数字for (int j = index; j < n - i - 1; j++) {numbers[j] = numbers[j + 1];}k %= factorial[n - 1 - i]; // 更新 k}return result;
}// 测试代码
int main() {int n = 4, k = 9;char* result = getPermutation(n, k);printf("第 %d 个排列是: %s\n", k, result);free(result); // 释放内存return 0;
}

代码解析

  1. 阶乘数组的计算

    factorial[0] = 1;
    for (int i = 1; i < n; i++) {factorial[i] = factorial[i - 1] * i;
    }
    
    • 用于快速获取 (n-1)!
  2. 维护可选数字

    for (int i = 0; i < n; i++) {numbers[i] = i + 1;
    }
    
    • 初始数字列表为 [1, 2, ..., n]
    • 每选定一个数字后,从列表中移除。
  3. 逐步构造排列

    int index = k / factorial[n - 1 - i]; // 当前数字的索引
    result[i] = numbers[index] + '0';    // 转为字符
    
    • 根据 k 确定当前位的数字索引。
    • 将对应数字从 numbers 中移除,更新 k
  4. 更新索引 k

    k %= factorial[n - 1 - i];
    
    • 剩余排列数更新为当前范围内的相对位置。
  5. 构造字符串

    • 动态分配内存存储结果,并在末尾添加字符串结束符。

复杂度分析

  1. 时间复杂度

    • 阶乘数组计算:O(n)
    • 每次确定一位数字需移除列表中的一个元素:O(n^2)
    • 总复杂度为 O(n^2)
  2. 空间复杂度

    • 需要额外的 O(n) 空间存储数字列表和阶乘数组。

测试案例

输入:
n = 4, k = 9
输出:
"2314"
输入:
n = 3, k = 3
输出:
"213"
http://www.lryc.cn/news/490045.html

相关文章:

  • 国际环境和背景下的云计算领域
  • logstash 解析数组格式json数据:split, json
  • Linux的开发工具(二)
  • Bokeh实现大规模数据可视化的最佳实践
  • Oracle表碎片整理与优化
  • 【华为云函数工作流】python的函数中如何获取请求链接中带的参数
  • 最新Kali安装详细版教程(附安装包,傻瓜式安装教程)
  • 【unity小技巧】unity最完美的CharacterController 3d角色控制器,实现移动、跳跃、下蹲、奔跑、上下坡、物理碰撞效果,复制粘贴即用
  • 66 mysql 的 表自增长锁
  • 神经网络问题之一:梯度消失(Vanishing Gradient)
  • 企业网页设计的安全与数据保护
  • 对 TypeScript 中类是怎么理解的?都有哪些应用场景?
  • 2024“龙信杯“电子数据取证竞赛-服务器取证题目Writeup
  • Label-studio-ml-backend 和YOLOV8 YOLO11自动化标注,目标检测,实例分割,图像分类,关键点估计,视频跟踪
  • Elasticsearch Windows版的安装及启动
  • 解决 VMware 嵌套虚拟化提示 关闭“侧通道缓解“
  • 基于Redis实现的手机短信登入功能
  • C# NetworkStream用法
  • 华三预赛从零开始学习笔记(每日编辑,复习完为止)
  • MySQL基础大全(看这一篇足够!!!)
  • [ 应急响应进阶篇-2 ] Linux创建后门并进行应急处置-1:超级用户帐号后门
  • 【无人机/平衡车/机器人】详解STM32+MPU6050姿态解算—卡尔曼滤波+四元数法+互补滤波
  • 数据结构-8.Java. 七大排序算法(上篇)
  • YOLOV5/rknn生成可执行文件部署在RK3568上
  • java http body的格式 ‌application/x-www-form-urlencoded‌不支持文件上传
  • GPU服务器厂家:为什么要选择 GPU 服务器?
  • Python操作neo4j库py2neo使用之py2neo 删除及事务相关操作(三)
  • Idea忽略提交文件、Idea设置文件隐藏、Idea提交时隐藏部分文件、git提交时忽略文件
  • python如何使用spark操作hive
  • 观察者模式和订阅模式