每日算法 -【Swift 算法】反转整数的陷阱与解法:Swift 中的 32 位整数处理技巧
反转整数的陷阱与解法:Swift 中的 32 位整数处理技巧
在面试题和算法练习中,整数反转是一道非常经典的题目。乍一看很简单,但一旦加入“不能使用 64 位整数”和“不能溢出 32 位整数范围”这两个限制,问题就立刻变得有挑战性。本文将带你深入剖析这道题,并用 Swift 实现一个健壮、符合题意的解决方案。
🧩 题目描述
给定一个 32 位有符号整数 x
,请你返回将 x
数字部分反转后 的结果。如果反转后整数超过了 32 位有符号整数的表示范围 [-2³¹, 2³¹ - 1]
,那么就返回 0。
举个例子:
输入: 123 → 输出: 321
输入: -123 → 输出: -321
输入: 1534236469 → 输出: 0(反转后溢出)
🧠 解题思路
这个问题的难点在于 处理可能的溢出情况,并且不能依赖 64 位整数类型。
思考步骤:
- 每次取出
x
的最后一位:pop = x % 10
- 将其添加到结果中:
result = result * 10 + pop
- 处理过程中要判断是否即将溢出
关键点:如何判断溢出?
反转之前:
result * 10 + pop
可能会超过 Int32 的范围,所以我们必须在计算之前判断是否 即将溢出:
if result > Int32.max / 10 || (result == Int32.max / 10 && pop > 7) {return 0
}
负数同理。
💻 Swift 实现(含详细中文注释)
func reverse(_ x: Int) -> Int {// 定义 32 位整数的最大值和最小值let INT_MAX = Int32.max // 2147483647let INT_MIN = Int32.min // -2147483648var x = x // 将参数复制到可变变量中,便于后续修改var result = 0 // 初始化反转结果为 0// 当 x 不为 0 时,继续处理while x != 0 {let pop = x % 10 // 取出最低位(如 123 % 10 = 3)x /= 10 // 去掉最低位(如 123 / 10 = 12)// ----------- 溢出判断开始 -----------// 如果 result > INT_MAX / 10,那么 *10 一定会溢出// 如果 result == INT_MAX / 10,还要判断 pop 是否超过最大个位数 7(2147483647 的最后一位)if result > Int(INT_MAX) / 10 || (result == Int(INT_MAX) / 10 && pop > 7) {return 0 // 正数溢出,返回 0}// 如果 result < INT_MIN / 10,那么 *10 一定会溢出// 如果 result == INT_MIN / 10,还要判断 pop 是否小于最小个位数 -8(-2147483648 的最后一位)if result < Int(INT_MIN) / 10 || (result == Int(INT_MIN) / 10 && pop < -8) {return 0 // 负数溢出,返回 0}// ----------- 溢出判断结束 -----------result = result * 10 + pop // 将当前位加入结果中(完成“反转”的核心操作)}return result // 返回最终的反转结果
}
✅ 补充说明
为什么只判断 pop > 7 和 pop < -8?
因为 32 位整数最大值是 2147483647
,最小值是 -2147483648
,个位分别是 7 和 -8,所以边界判断时只需要关注个位数。
🔍 调试小技巧
你可以在 while
循环内部加上:
print("pop = \(pop), result = \(result), x = \(x)")
用来调试每一步取数和构建过程,非常适合教学和面试时解释思路。
📌 总结
这道题不光考察了基本的数学操作,还测试了你对 整数范围和边界条件的敏感性,是许多面试官非常喜欢的一道算法题。通过合理的判断条件,我们可以在不使用任何 64 位数据类型的情况下,完成这个操作,符合题目所有要求。
🎁 如果你想瞅瞅允许使用 64 位整数解法👇
func reverse(_ x: Int) -> Int {var x = xvar result: Int64 = 0 // 使用 64 位整数防止中间过程溢出while x != 0 {let pop = x % 10x /= 10result = result * 10 + Int64(pop)}// 最后检查是否落在 32 位整数范围内if result < Int64(Int32.min) || result > Int64(Int32.max) {return 0}return Int(result) // 转换回 Int(假设 Int 是 32 位或 64 位都没关系)
}
使用场景选择
• 如果你明确知道平台支持 64 位整数(如大部分 iOS/macOS 平台的 Int 实际是 64 位),并且题目没有禁止,使用 Int64 是更安全也更清晰的做法。
• 但在算法题或面试中,如果题目要求 “不能使用 64 位整数”,那就必须用前面那种严格的按位判断方式。