leetcode_rust/problems_cn/p000_0xx/p000_007.rs
1//! # 题目说明
2//! 给你一个 32 位的有符号整数 `x` ,返回将 `x` 中的数字部分反转后的结果。
3//!
4//! 如果反转后整数超过 32 位的有符号整数的范围 $[−2^{31}, 2^{31} − 1]$ ,就返回 0。
5//!
6//! 假设环境不允许存储 64 位整数(有符号或无符号)。
7//!
8//! | 示例 1 |
9//! | :-- |
10//! | 输入:x = 123 |
11//! | 输出:321 |
12//!
13//! | 示例 2 |
14//! | :-- |
15//! | 输入:x = -123 |
16//! | 输出:-321 |
17//!
18//! | 示例 3 |
19//! | :-- |
20//! | 输入:x = 120 |
21//! | 输出:21 |
22//!
23//! | 示例 4 |
24//! | :-- |
25//! | 输入:x = 0 |
26//! | 输出:0 |
27//!
28//! 提示:
29//!
30//! - $-2^{31} \leqslant x \leqslant 2^{31} - 1$
31//!
32//! 来源:<https://leetcode.cn/problems/reverse-integer>
33
34////////////////////////////////////////////////////////////////////////////////
35
36/// 32 位整型反转的同时检查溢出
37///
38///
39/// # 参数
40/// * `x` - 32 位有符号整数
41///
42/// ```
43/// use leetcode_rust::problems_cn::p000_0xx::p000_007::reverse_integer;
44/// assert_eq!(reverse_integer(-2147483647), 0);
45/// assert_eq!(reverse_integer(123), 321);
46/// assert_eq!(reverse_integer(120), 21);
47/// assert_eq!(reverse_integer(-123), -321);
48/// ```
49pub fn reverse_integer(x: i32) -> i32 {
50 reverse_s1(x)
51}
52
53/// 解法一:32 位整型反转的同时检查溢出
54///
55/// # 参数
56/// * `x` - 32 位有符号整数
57fn reverse_s1(x: i32) -> i32 {
58 let mut temp_stack: Vec<u8> = vec![];
59 // 将无符号数转换为数字数组
60 for ch in x.to_string().as_bytes() {
61 if *ch != 45 {
62 temp_stack.push(*ch);
63 }
64 }
65 loop {
66 // 去除结尾的数字 0
67 match temp_stack.last() {
68 Some(last_ch) => {
69 if *last_ch == 48 && temp_stack.len() > 1 {
70 temp_stack.pop();
71 } else {
72 break;
73 }
74 }
75 None => break,
76 }
77 }
78 temp_stack.reverse();
79
80 // 正数的溢出阈值为 2147483647(包含符号)
81 let mut overflow_at_u8: [u8; 10] = [50, 49, 52, 55, 52, 56, 51, 54, 52, 55];
82 let mut target: Vec<u8> = vec![];
83 // 检测输入值的符号并据此更新判断溢出的阈值
84 if x < 0 {
85 target.push('-' as u8);
86
87 // 负数的溢出阈值为 2147483648(不包含符号)
88 overflow_at_u8 = [50, 49, 52, 55, 52, 56, 51, 54, 52, 56];
89 }
90
91 // 在无符号的状态下检查溢出
92 if temp_stack.len() >= overflow_at_u8.len() {
93 for idx in 0..overflow_at_u8.len() {
94 if temp_stack[idx] < overflow_at_u8[idx] {
95 // 如果某一位数值比溢出值要小,则没有必要检查后续的各位数值
96 break;
97 }
98 if temp_stack[idx] > overflow_at_u8[idx] {
99 // 上一个数值(如果存在)位置的目标值和阈值相同,
100 // 如果当前位的目标值大于阈值则表示溢出
101 return 0;
102 }
103 }
104 }
105 // 结合符号和数字
106 target = [target, temp_stack].concat();
107 String::from_utf8(target).unwrap().parse::<i32>().unwrap()
108}