1. 问题背景与定义
旋转数字问题最初出现在LeetCode第788号题目中,属于字符串处理与数学结合的经典面试题型。题目要求我们统计在1到N的范围内,有多少个数是"好数"(good number)。这里的"好数"定义非常特殊:当这个数的每一位数字旋转180度后,得到的数字与原来不同且仍然是一个有效的数字。
数字旋转规则如下:
- 0,1,8旋转后仍然是自身
- 2旋转后变成5
- 5旋转后变成2
- 6旋转后变成9
- 9旋转后变成6
- 3,4,7旋转后无法形成有效数字
举个例子:
- 数字"2"旋转后变成"5",属于好数
- 数字"12"旋转后变成"15",也属于好数
- 数字"10"旋转后仍然是"10",不属于好数(因为旋转前后相同)
- 数字"34"旋转后无效(因为包含3),不属于好数
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题思路分析
2.1 暴力解法可行性评估
最直观的解法是遍历1到N的每个数字,检查其是否满足好数条件。对于每个数字:
- 将其转换为字符串
- 检查每个字符是否属于可旋转数字(0,1,2,5,6,8,9)
- 如果全部字符都可旋转,则进行旋转操作
- 比较旋转前后的数字是否不同
这种方法的时间复杂度是O(N*L),其中L是数字的平均位数。当N较大时(比如N=1e5),这种解法在面试中可能不够高效。
2.2 数学性质观察
通过观察可以发现,好数必须满足两个条件:
- 不包含任何无效数字(3,4,7)
- 至少包含一个可变化数字(2,5,6,9)
这提示我们可以将问题分解为:
- 首先排除包含3,4,7的数字
- 然后在剩余数字中找出至少包含一个2,5,6,9的数字
2.3 动态规划思路
这个问题可以建模为数字的排列组合问题,适合用动态规划解决。我们可以定义:
- dp[i][eq][hasGood] 表示处理到第i位时的状态
- eq表示当前数字是否等于N的前i位
- hasGood表示是否已经包含可变化数字
通过状态转移,我们可以高效计算出好数的数量,而不需要逐个检查。
3. 具体实现方案
3.1 暴力解法实现
虽然暴力解法不是最优解,但作为基础实现,可以帮助理解问题:
python复制def rotatedDigits(N):
count = 0
