坚持坚持再坚持!无论错多少遍!你总能做出来的
下面贴上leetcode的一道简单的题目 :
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1: |
输入: 123 |
输出: 321 |
示例 2: |
输入: -123 |
输出: -321 |
示例 3: |
输入: 120 |
输出: 21 |
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 。请根据这个假设,如果反转后整数溢出那么就返回 0。
来源:力扣(LeetCode)
难点 : 溢出判断
用较低位作为解题的例子, 方便可视化演示 :
假设输入一个数,并将其数字倒序输出, 如果超出范围为, 则判断为溢出, 返回0.
示例 1: |
输入 : 59 |
输出 : 95 |
示例 2: |
输入 : 159 |
输出 : 0 |
此时, 假设输入整数 : 159, 倒序过程中判断为溢出, 输出结果应为0
question1 : 那么我们该如何判断它溢出呢 ?
首先确定范围为, 我们打算将从最低位开始一位一位地反转, 将每一位取出后存储到一个变量中, 判断该变量是否已经大于正边界值的前位或小于负边界值的前位......
question 2 : 为什么是判断而不是呢 ?
在溢出判断时, 我们最关心的是它最可能在什么时候溢出和最容易判断出它在哪里溢出, 那就是在最接近边界值的时候会溢出, 请看下面的图示
在每一位被取出时, 都与边界值的前位的数值进行比较, 这样的好处就是当被反转的数准备取下一位进行反转时, 已经被反转的数值的位数有可能是位, 那么如果此时如果该值已经大于正边界值的前位的值或小于负边界值的前位的值, 那么下一位已经没有必要再取出来作反转了, 因为前位的数值已经溢出了, 下一位再添加上去, 也必定溢出
补充 : 为什么是有可能 ?
因为反转的位数取决于用户输入的数字 , 如果输入的数字位数根本没有到位, 例如 : 38, 那么一定不会溢出, 但是如果输入的数字原本是和边界值位数相同, 此时在最后一位被反转时, 已经被反转的数值的位数刚好是位
question3 : 如果反转后的数值和边界值的前位都相同, 那该怎么办 ?
这就是"强强对碰"了 , 胜负决定在第位, 如果原来的数值的第n位数值比负边界值还小或比正边界值大, 那么这个数就溢出, 因为第n位必定会跟在反转数值的最后一位
附上程序代码, 这段代码和leetcode上许多大牛写的答案是差不多的, 代码我都懂, 思想最重要!
public class Solution {
public int reverse(int x) {
int ans = 0;
while (x != 0){
//取末位数字
int pop = x % 10;
//如果反转的数字大于整型的前n-1位, 则溢出
//或者反转后的数字刚好等于整型最大值的前n-1位, 但最后一位大于整型的最后一位, 也溢出
if (ans > Integer.MAX_VALUE / 10 || ans == Integer.MAX_VALUE / 10 && pop > Integer.MAX_VALUE % 10){
return 0;
}else if (ans < Integer.MIN_VALUE / 10 || ans == Integer.MIN_VALUE / 10 && pop < Integer.MIN_VALUE % 10){
return 0;
}else{
ans = ans * 10 + pop;
x /= 10;
}
}
return ans;
}
}