当前位置: 首页 > 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.hn-smt.com/news/9712/

相关文章:

  • CTFHub 命令注入-综合练习 WP
  • 2025年11月美国投资移民机构榜单:十家实力排名与多维评测
  • 2025年评价高的地暖挤塑板实力厂家TOP推荐榜
  • 2025年口碑好的EPE珍珠棉发泡机厂家最新TOP排行榜
  • 2025年评价高的烫金烫银金丝绒热门厂家推荐榜单
  • 2025年热门的称重模块生产TOP实力厂家推荐榜
  • 新农合交费
  • 2025年知名的海运出口包装袋TOP品牌厂家排行榜
  • 2025年评价高的大跨距电缆桥架品牌厂家排行榜
  • 2025年评价高的卫浴缓冲隐藏轨厂家最新用户好评榜
  • 退役选手也要写 CSP 游记
  • 没有素质的J+S
  • 2025年评价高的三段力液压铰链厂家最新权威实力榜
  • 2025年比较好的双功能缓冲隐藏轨厂家最新实力排行
  • 2025年评价高的装箱机高评价厂家推荐榜
  • 2025年知名的密码家用智能门锁厂家选购指南与推荐
  • 2025 年 11 月电缆绝缘材料厂家最新推荐,聚焦高端定制需求与全案交付能力
  • 2025年评价高的电动护理床厂家最新TOP实力排行
  • 2025年评价高的室外冰雕厂家推荐及采购指南
  • 2025年比较好的耐丙酮涂料厂家最新实力排行
  • 2025年比较好的广东保险柜厂家最新推荐排行榜
  • 2025年知名的三维调节针式铰链最新TOP品牌厂家排行
  • 2025年口碑好的微波真空干燥设备高评价厂家推荐榜
  • 2025年评价高的开炼机厂家最新推荐排行榜
  • 应对价值表征困境——从静态表征到动态演化
  • 《天鹰战士 最后的冲击》观后感
  • Day9综合案例一
  • Scala语法
  • 2025 年 11 月废水蒸发器厂家权威推荐榜:MVR/薄膜刮板/单效/双效/三效/多效/高盐/含盐/降膜/结晶/mvr母液/氯化钠/硫酸铵/垃圾渗滤液/化工废水刮板/强制循环/废水脱盐蒸发器厂家精选
  • 2025 年 11 月防静电地板厂家推荐排行榜,全钢/全钢陶瓷/硫酸钙/铝合金/pvc架空/防静电地板,OA网络地板,机房防静电地板,办公室网络架空地板公司精选