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

386. 字典序排数

386. 字典序排数

理解题目要求

题目要求我们生成从 1 到 n 的整数的字典序排列,并且要求:

  • 时间复杂度 O(n)​​:不能使用直接排序(通常指的是使用标准的排序算法(如快速排序、归并排序、堆排序等)对数据进行排序。这些排序算法的时间复杂度通常是 ​O(n log n)​,而题目要求的是 ​O(n)​​ 的时间复杂度,因此不能直接使用这些排序方法。)。
  • 空间复杂度 O(1)​​:不能使用额外的数组或数据结构存储中间结果。

字典序的定义

字典序(lexicographical order)是指按照字符串的字典顺序排列数字。例如:

  • 1, 10, 100, 101, ..., 11, 110, ..., 2, 20, 200, ..., 3, 30, ...

关键观察

字典序可以看作是一个前缀树(Trie)​的深度优先遍历(DFS)顺序:

  • 从 1 开始,尽可能往更深的位数扩展(即 ×10)。
  • 如果无法继续扩展(比如 ×10 > n),则回溯到上一层(即 //10),并尝试 +1

算法思路

  1. 初始化​:从 number = 1 开始。
  2. 尝试扩展(×10)​​:
    • 如果 number × 10 ≤ n,则 number × 10 是下一个字典序数字。
    • 否则,无法继续扩展,进入回溯阶段。
  3. 回溯(//10)并递增(+1)​​:
    • 如果 number % 10 == 9 或 number + 1 > n,说明当前层已经遍历完,需要回溯到上一层(number //= 10)。
    • 否则,number + 1 是下一个字典序数字。
  4. 终止条件​:已经收集 n 个数字。

示例

以 n = 13 为例:

  1. 1 → 10(1×10)
  2. 10 → 11(10 +1)
  3. 11 → 12(11 +1)
  4. 12 → 13(12 +1)
  5. 13 → 2(13 +1 >13,回溯到 1,然后 1 +1=2
  6. 2 → 3(2 +1)
  7. 3 → 4(3 +1)
    ... 直到收集 n 个数字。

代码实现

def lexicalOrder(n):res = []number = 1for _ in range(n):res.append(number)if number * 10 <= n:number *= 10else:while number % 10 == 9 or number + 1 > n:number //= 10number += 1return res

时间复杂度分析

  • 每个数字 1..n 被处理一次,且每次操作是 O(1),所以总时间复杂度是 ​O(n)​
  • 只用了常数空间存储 number 和 res(输出结果不计入空间复杂度),所以空间复杂度是 ​O(1)​

为什么能保证 O(n) 时间?

  • 每次操作要么 ×10(深度优先),要么 +1(广度优先),不会重复处理数字。
  • 每个数字只会被访问一次,且操作是常数时间。

为什么能保证 O(1) 额外空间?

  • 除了输出结果 res 外,只用了 number 这个变量,没有递归或额外数据结构。

总结

这个算法巧妙地利用了字典序的DFS遍历特性:

  1. 优先往深层扩展(×10)。
  2. 无法扩展时回溯并递增(//10 然后 +1)。
  3. 整个过程不重复、不遗漏,严格 O(n) 时间、O(1) 空间。

 

http://www.lqws.cn/news/440821.html

相关文章:

  • 解码成都芯谷金融中心:文化科技产业园的产融创新生态密码
  • 2025年八大科技趋势
  • Spring Boot + MyBatis + Vue:构建高效全栈应用的实战指南
  • bos_token; eos_token; pad_token是什么
  • 农村土地经营权二轮延包—一键生成属性数据库MDB
  • 解决docker pull镜像慢的问题
  • 【设计模式】用观察者模式对比事件订阅(相机举例)
  • 【分布式】基于Redisson实现对分布式锁的注解式封装
  • 【JavaEE】(3) 多线程2
  • API网关Apisix介绍
  • MySQL高可用方案解析与选型指南
  • Android图形系统框架解析
  • 【MySQL基础】MySQL内置函数全面解析:提升你的数据库操作效率
  • AI与大数据如何驱动工业品电商平台的智能决策?
  • mongodb单节点改副本集模式
  • Spring Boot + MyBatis + Vue:打造高效全栈应用的黄金组合
  • CppCon 2017 学习:Esoteric Data Structures and Where to Find Them
  • 《汇编语言:基于X86处理器》第2章 复习题
  • infinisynapse 使用清华源有问题的暂时解决方法:换回阿里云源并安装配置PPA
  • flink的多种部署模式
  • YOLOv8改进:Neck篇——2024.1全新MFDS-DETR的HS-FPN特征融合层解析
  • 使用 rsync 拉取文件(从远程服务器同步到本地)
  • Mac 安装ElasticSearch和Kibana详细教程
  • 【面试题002】synchronized和lock的区别
  • C#最佳实践:为何优先使用查询语法而非循环
  • Kafka使用Elasticsearch Service Sink Connector直接传输topic数据到Elasticsearch
  • 清除 docker 无用的 镜像/容器
  • 国产Linux银河麒麟操作系统安装中望CAD和开源社区版QCAD软件
  • python智慧物业管理系统
  • 数据差异的iOS性能调试:设备日志导出和iOS文件管理