返回

LeetCode 精粹:第 K 小字典序数字,算法制胜之道

前端







**导言** 

在计算机科学的广阔领域中,算法发挥着至关重要的作用。算法是解决问题的明确而有条理的方法,是程序员必不可少的工具。LeetCode 是一个在线平台,提供了一系列算法挑战,帮助程序员提高他们的算法技能。

本文将深入探讨 LeetCode 题目 440:“字典序的第 K 小数字”,为您提供一个分步指南,了解其算法思维和实现。

**理解问题** 

给定两个正整数 n 和 k,题目要求找出 [1, n] 范围内的第 k 小字典序数字。字典序是指数字按其在字典中的顺序排列。例如,在 [1, 10] 范围内,字典序的第 3 小数字是 3。

**算法思维** 

解决此问题的关键在于认识到字典序实际上是一个二叉搜索树。我们可以将 [1, n] 视为一棵二叉树,其中每个节点表示一个数字。每个节点有左子树和右子树,左子树包含比当前数字小的所有数字,而右子树包含比当前数字大的所有数字。

**算法步骤** 

1. **初始化**   - 设置一个指向根节点的指针 root。
   - 将 k 减 1,因为根节点本身就是字典序的第一个数字。

2. **遍历**   - 如果 root 的左子树包含的数字个数大于或等于 k,则转到步骤 3。否则,转到步骤 4。

3. **左子树**   - 将 root 替换为其左子树。
   - 将 k 减去 root 的左子树包含的数字个数。

4. **右子树**   - 将 root 替换为其右子树。

5. **返回**   - 当 k 等于 0 时,返回 root 的值。

**示例代码** 

```python
def findKthNumber(n, k):
  # 初始化指针和 k
  root = 1
  k -= 1

  while k > 0:
    # 获取左子树的数字个数
    left_count = count_nodes(root * 10)

    # 如果左子树包含的数字个数大于或等于 k
    if left_count >= k:
      # 转到左子树
      root = root * 10
    else:
      # 转到右子树
      root = root * 10 + 1
      # 减去左子树的数字个数
      k -= left_count

  # 返回第 k 小数字
  return root

def count_nodes(n):
  # 计算 n 的位数
  num_digits = len(str(n))

  # 计算 [1, n] 范围内每位数字的节点个数
  count = 0
  for i in range(1, num_digits + 1):
    count += 9 * 10 ** (i - 1)

  # 添加 n 本身的节点个数
  count += n - 10 ** (num_digits - 1) + 1

  return count

结论

通过深入剖析 LeetCode 题目 440:“字典序的第 K 小数字”,我们了解了算法思维在解决计算机科学问题中的重要性。我们一步步分解了算法,提供了清晰的实现步骤和示例代码,帮助您掌握解决此类问题的技能。

LeetCode 是提高算法技能的宝贵资源,通过不断练习和解决挑战,您可以提升您的编程能力,为技术面试做好准备。拥抱算法思维,开启您成功的技术之旅!