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

386. 字典序排数

这个问题是经典的 "字典序排序"(Lexicographical Order)问题,要求按字典序输出 [1, n] 的数字,并且要求 O(n) 时间O(1) 额外空间(不包括输出占用的空间)。


思路分析

字典序比较规则:

  • 比较数字的字符串形式,例如 102 之前,因为 "10" < "2" 按字符串比较。

直接排序会超过 O(n) 时间,所以需要用 DFS 风格的生成方法 来按字典序遍历。

核心思想

  • 从 1 到 9 开始,对每个数字 curr
    • 先输出 curr
    • 然后递归地(或迭代地)处理 curr * 10curr * 10 + 9 的数字,只要它们 <= n
  • 这实际上是在遍历一个 十叉树 的先序遍历。

算法步骤(迭代 / 模拟 DFS)

我们可以用迭代来避免递归栈空间,实现 O(1) 额外空间(除了输出列表)。

  1. 初始化 curr = 1
  2. 循环直到处理完所有数字:
    • curr 加入结果
    • 如果 curr * 10 <= n,则进入下一层(更长的数字前缀)
    • 否则:
      • 如果 curr % 10 == 9curr + 1 > n,则回溯到上一层(curr = curr / 10
      • 否则 curr++
  3. 直到 curr == 1 且需要回溯时结束(实际可判断结果数量达到 n 个停止)

代码实现

/*** @param {number} n* @return {number[]}*/
var lexicalOrder = function(n) {const result = [];let curr = 1;for (let i = 0; i < n; i++) {result.push(curr);if (curr * 10 <= n) {// 进入下一层:curr -> curr * 10curr *= 10;} else {// 到达该层末尾或 n 的限制if (curr >= n) {curr = Math.floor(curr / 10);}curr += 1;// 跳过末尾0,直接进位while (curr % 10 === 0) {curr = Math.floor(curr / 10);}}}return result;
};

更清晰的迭代实现(推荐)

var lexicalOrder = function(n) {const result = [];let num = 1;for (let i = 0; i < n; i++) {result.push(num);if (num * 10 <= n) {num *= 10; // 深度优先:先走最左路径} else {// 回溯:如果到了末尾或超出 n,则回到上层if (num >= n) {num = Math.floor(num / 10);}num += 1;// 处理进位产生的末尾0while (num % 10 === 0) {num = Math.floor(num / 10);}}}return result;
};

示例

输入:n = 13
输出:[1,10,11,12,13,2,3,4,5,6,7,8,9]

执行过程(简略):

  • 1 → 10 → 11 → 12 → 13 → 回溯到 1 → 2 → 3 ... → 9

复杂度分析

  • 时间复杂度:O(n),每个数字恰好处理一次。
  • 空间复杂度:O(1) 额外空间(不包括存储结果的数组)。

好的,我来详细解释 DFS 风格的生成方法 来解决字典序排序问题。

核心思想

把数字 1~n 看作一个 十叉树

  • 根节点是空字符串
  • 每个节点的子节点是在末尾添加 0~9
  • 先序遍历 这棵树,就得到字典序

例如 n=20:

        (root)/  |  \1   2   3...9/|\10 11 12...19/100... (但>20,停止)

DFS 递归实现

var lexicalOrder = function(n) {const result = [];function dfs(current) {if (current > n) return;if (current > 0) {result.push(current);}// 对当前数字,尝试添加 0~9for (let i = 0; i <= 9; i++) {if (current === 0 && i === 0) continue; // 避免 "0"const next = current * 10 + i;if (next > n) break; // 提前终止dfs(next);}}dfs(0); // 从0开始,但跳过0本身return result;
};

问题:递归会使用 O(log n) 的栈空间,不完全符合 O(1) 空间要求。


迭代 DFS(O(1) 空间)

模拟 DFS 的栈行为,但不实际用栈:

var lexicalOrder = function(n) {const result = [];let curr = 1;for (let i = 0; i < n; i++) {result.push(curr);if (curr * 10 <= n) {// DFS 深入:往左子树走 (curr * 10)curr *= 10;} else {// 到达当前分支末尾,需要回溯if (curr >= n) {curr = Math.floor(curr / 10);}curr += 1;// 跳过末尾的0,比如 19 -> 20 应该变成 2while (curr % 10 === 0) {curr = Math.floor(curr / 10);}}}return result;
};

DFS 遍历的直观理解

以 n=13 为例,DFS 遍历路径:

1 → 10 → 11 → 12 → 13 → 回溯 → 2 → 3 → 4 → ... → 9

DFS 规则

  1. 如果能 ×10 还在 n 内,就 ×10(往深层走)
  2. 否则 +1(同层下一个)
  3. 如果 +1 后超过 n 或进位了,就回溯到上层

带详细注释的版本

var lexicalOrder = function(n) {const result = [];let num = 1;for (let i = 0; i < n; i++) {result.push(num);// 1. 优先往深层走:num -> num*10if (num * 10 <= n) {num *= 10;} else {// 2. 当前层遍历完毕或超出n,需要调整if (num >= n) {// 如果当前数已经>=n,回溯到上一层num = Math.floor(num / 10);}num += 1;// 3. 处理进位:比如 199 -> 200 应该变成 2while (num % 10 === 0) {num = Math.floor(num / 10);}}}return result;
};

为什么这是 DFS?

  • 深度优先:总是先尝试在当前数字后面加 0(×10),进入更"深"的数字
  • 回溯:当不能再加深时(×10 > n),回到上一层继续
  • 这正好对应树的 先序遍历:根 → 左子树 → 右子树

复杂度分析

  • 时间:O(n) - 每个数字恰好输出一次
  • 空间:O(1) - 只用了几个变量

这种方法完美满足了题目的要求,既高效又节省空间。

http://www.jsqmd.com/news/29032/

相关文章:

  • 2025年11月网站建设公司推荐:央国企与博物馆共同选择的十家
  • 2025年11月中国员工福利公司榜:十家主流平台对比解析
  • 2025年11月背单词软件推荐评测:宠光单词宝宝等五款工具深度解析
  • 2025年11月亲子旅游景区推荐:热门榜对比指南
  • 2025年11月背单词软件评测榜:从自定义词库到数据留存全维度对比
  • 2025年11月亲子旅游景区评测榜:十强真实表现与家庭出游决策指南
  • 2025 年 11 月污水处理厂生物除臭设备,餐厨垃圾生物除臭设备,垃圾中转站生物除臭设备厂家最新推荐,聚焦跨平台能力与售后体系的实用指南
  • 关于码代码的编辑器和字体 sublime text 和 JetBrains Maple Mono
  • CTFHub 命令注入-综合练习 WP
  • C++语法—类的继承
  • 2025 年 11 月印染厂污水生物除臭设备,污水站生物除臭设备,屠宰场生物除臭设备厂家最新推荐,聚焦高端定制需求与全案交付能力
  • 2025 年 11 月污水处理厂生物除臭设备,污水泵站生物除臭设备,厨余垃圾生物除臭设备厂家最新推荐,高性能与可靠性兼具的优质品牌
  • 2025年11月超声波清洗机厂家榜单:性能与口碑双轨对比
  • 2025 年 11 月印染厂污水生物除臭设备,食品厂污水生物除臭设备,屠宰场生物除臭设备厂家最新推荐,实力品牌深度解析采购无忧之选!
  • 2025年11月超声波清洗机厂家排行:五家主流品牌深度评测
  • 2257. 统计网格图中没有被保卫的格子数
  • 2025年11月白茶品牌榜单:北路领衔五强横向评测
  • 在UOS中浏览NAS图片
  • 未来编程
  • 基于MATLAB与Zemax动态数据交换(DDE)工具箱
  • 2025年11月婴幼儿润肤乳产品推荐榜:五款人气单品横向对比
  • 2025年11月婴幼儿润肤乳产品推荐榜:五款安心型号客观评价
  • 2025年11月婴幼儿润肤乳产品推荐排行:从天然成分到锁水力全面评价
  • 2025年11月珠海酒店排行:日月贝旁丽怡酒店与九家高分店对比榜
  • 2025年11月成都律师事务所排行榜:十家机构权威对比与实用指南
  • 2025年11月珠海酒店评价榜:丽怡情侣路店对比九家真实口碑全记录
  • 2025年11月合肥建筑律师评测榜:十强律所服务与胜诉率排名
  • 2025年11月合肥建筑律师推荐榜:建设工程案件代理对比
  • 大模型基础补全计划(六)---带注意力机制的seq2seq实例与测试(Bahdanau Attention)
  • 25岁的一天与M2002RTC