1. 整数反转问题概述
LeetCode第7题"整数反转"是算法入门阶段的经典题型,要求将一个32位有符号整数进行数字位反转。例如输入123输出321,输入-123输出-321。这个问题看似简单,却涵盖了整数处理、边界条件判断等编程基本功。
在实际工程中,类似操作常见于数据校验、密码生成等场景。比如银行系统需要对交易流水号进行可逆变换时,就会用到这类算法。掌握这个基础问题的多种解法,能帮助我们建立扎实的编程思维。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 数学解法详解
2.1 核心算法思路
数学法的本质是通过不断取模和除法运算来拆解原始数字。具体步骤:
- 初始化结果变量res为0
- 当x不等于0时循环:
- 取x的个位数:pop = x % 10
- 将x右移一位:x = x // 10
- 检查结果是否溢出:if res > INT_MAX//10 or (res == INT_MAX//10 and pop > 7)
- 检查结果是否下溢:if res < INT_MIN//10 or (res == INT_MIN//10 and pop < -8)
- 更新结果:res = res * 10 + pop
关键点:Python的整数除法//会向负无穷取整,与C++等语言的截断除法不同,这是Python处理负数时的优势
2.2 完整实现代码
python复制def reverse(x: int) -> int:
INT_MAX = 2**31 - 1
INT_MIN = -2**31
res = 0
while x != 0:
pop = x % 10 if x > 0 else -(-x % 10) # 处理Python负数取模特性
x = x // 10 if x > 0 else -(-x // 10) # 保持向零截断
if res > INT_MAX // 10 or (res == INT_MAX // 10 and pop > 7):
return 0
if res < INT_MIN // 10 or (res == INT_MIN // 10 and pop < -8):
return 0
res = res * 10 + pop
return res
2.3 边界条件处理
32位有符号整数的范围是[-2³¹, 2³¹-1],即[-2147483648, 2147483647]。反转后的数字可能超出这个范围,需要特别处理:
- 正数溢出:当res > INT_MAX//10,或res == INT_MAX//10且pop>7时
- 负数下溢:当res < INT_MIN//10,或res == INT_MIN//10且pop<-8时
3. 字符串解法详解
3.1 字符串转换思路
字符串法利用Python的字符串操作特性:
- 将整数转为字符串
- 反转字符串
- 处理负号和前导零
- 转换回整数并检查溢出
python复制def reverse_str(x: int) -> int:
s = str(x)
if s[0] == '-':
rev = '-' + s[:0:-1] # 保留负号并反转数字部分
else:
rev = s[::-1]
res = int(rev)
return res if -2**31 <= res <= 2**31-1 else 0
3.2 性能对比分析
| 方法 | 时间复杂度 | 空间复杂度 | 适用场景 |
|---|---|---|---|
| 数学法 | O(log₁₀x) | O(1) | 内存敏感环境 |
| 字符串法 | O(log₁₀x) | O(log₁₀x) | 快速原型开发 |
数学法虽然代码稍复杂,但不需要额外字符串存储空间。字符串法代码简洁,但会创建临时字符串对象。
4. 常见问题与优化技巧
4.1 Python负数处理陷阱
Python的取模运算与C++等语言不同:
- C++中:-123 % 10 = -3
- Python中:-123 % 10 = 7
解决方法:
python复制pop = x % 10 if x > 0 else -(-x % 10)
4.2 溢出检查优化
可以预先计算边界值避免重复计算:
python复制INT_MAX_10 = INT_MAX // 10
INT_MAX_LAST = INT_MAX % 10
INT_MIN_10 = INT_MIN // 10
INT_MIN_LAST = INT_MIN % 10
4.3 测试用例设计
完整测试应包含:
- 普通正数(如123)
- 普通负数(如-456)
- 个位数(如7)
- 末尾有零的数(如1200)
- 边界值(2147483647, -2147483648)
- 反转后溢出的数(如1534236469)
5. 工程实践中的应用
5.1 数据校验场景
在金融系统中,账号校验码常通过数字变换生成。例如:
python复制def generate_check_code(account_num):
reversed_num = reverse(account_num)
return (account_num + reversed_num) % 97
5.2 性能敏感场景优化
对于高频调用的场景,可以使用位运算加速:
python复制def reverse_fast(x):
sign = -1 if x < 0 else 1
x *= sign
res = 0
while x:
res = res * 10 + x % 10
x //= 10
res *= sign
return res if -2**31 <= res <= 2**31-1 else 0
6. 算法扩展思考
6.1 浮点数反转
处理浮点数时需要考虑小数点位:
python复制def reverse_float(x: float) -> float:
s = str(x)
if '.' in s:
int_part, dec_part = s.split('.')
rev = int_part[::-1] + '.' + dec_part[::-1]
else:
rev = s[::-1]
return float(rev)
6.2 链表数字反转
类似问题还有链表表示的数字反转:
python复制class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def reverse_list(head: ListNode) -> ListNode:
prev = None
while head:
next_node = head.next
head.next = prev
prev = head
head = next_node
return prev
在实际编码面试中,我建议优先使用数学解法,因为它能更好展示对计算机底层运算的理解。字符串法虽然简洁,但可能让面试官觉得取巧。无论哪种方法,都要特别注意边界条件的处理,这是区分普通和优秀工程师的关键。
