0007. 整数反转 Reverse Integer
这是一个数学问题. 它考察的知识有这几个方面:
- 如何从十进制的整数中提取出各个位的值
- 如何从各个位的值重新组装一个整数
- 如何处理整数边界溢出的问题
接下来我们分别来说说.
从十进制的整数中提取出各个位的值
要使用 除10
的操作, 进行十进制的右移.
#![allow(unused)] fn main() { let mut x = 1234; while x != 0 { println!("unit value: {}", x % 10); x /= 10; } }
看图:
重新组装整数
如何从各个位的值重新组装一个整数? 使用相反的操作, 乘10
, 进行十进制的左移操作.
#![allow(unused)] fn main() { let mut number = 0; let bits = &[4, 3, 2, 1]; for bit in bits { number = number * 10 + bit; } println!("number: {number}"); }
看图:
整数溢出
如何处理整数边界溢出的问题? 在组装新的整数时, 可以让当前的值 *10
后与 i32::MAX .. i32::MIN
进行比较, 看在不在这个范围内.
number > i32::MAX / 10 || number < i32::MIN / 10
要注意的一点是, 不能使用 number * 10 > i32::MAX
这样的写法, 因为 number * 10
本身就可能溢出了!
基于以上3点, 编写出最终的代码:
#![allow(unused)] fn main() { #[allow(clippy::manual_range_contains)] pub fn reverse(x: i32) -> i32 { let mut x = x; let mut rev = 0; // x == 0 时, 表示它的所有整数进位值都被提取完了. while x != 0 { // 检查 rev 在添加新的个位值后是否会溢出 if rev > i32::MAX / 10 || rev < i32::MIN / 10 { return 0; } // 从 x 中提取出个位的值, 然后作为新的个位数值, 添加到 rev 上. rev = rev * 10 + x % 10; x /= 10; } rev } }