题目来源:leetcode Reverse Integer
Given a 32-bit signed integer, reverse digits of an integer.
Example 1: Example 2: Example 3:
Input: 123 Input: -123 Input: 120
Output: 321 Output: -321 Output: 21
Note:
Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.
思路:
- 考虑三种情况:
- 数值本身就溢出。
- 数值将要溢出,分界在未知数与INT_MAX位数相同。
- 数值在安全范围内。
- 解决方案:
- 先判断溢出,若溢出直接返回0
- 边按位比较,边倒转,判断溢出,若溢出返回0
- 直接倒转
前提处理:
1 int m=x,i=1,ten=1;//i记录位数,ten记录最高位数要*10的 2 while(m/=10){ ++i;ten*=10;} 3 if(i<10) m=reversemin(x,i,ten); 4 else m=reversemax(x,i,ten);
判断数值溢出:
1 unsigned int y = x;//扩大范围
2 if(x<0) y=-x;
3 if(y>INT_MAX) return 0;
按位比较,并倒转:
1 int reversemax(int x,int i,int ten) 2 { 3 int sign=1; 4 if(x<0) {x=-x; sign=-1;}//负数变为正数,sign还原负数 5 int m=0,max=INT_MAX; 6 while (i--) { 7 int rest = x % 10; 8 int mrest=max/ten; 9 if(rest>mrest) return 0;//与INT_MAX按位比较,如果大于则已经溢出,返回0 10 else if(rest<mrest) break;//如果小于则进入了安全范围,跳到安全的倒转 11 m += rest * ten;//只有在相等的情况才需要进行下一次比较 12 x /= 10; 13 max=max-mrest*ten; 14 ten /= 10; 15 } 16 if(ten==0) return m*sign; 17 ++i;//最后一次循环中止时,没有操作,所以还原被删去的位数 18 19 while (i--) {//正常倒转 20 int rest = x % 10; 21 m += rest * ten; 22 x /= 10; 23 ten /= 10; 24 } 25 return m*sign; 26 27 }
!负数取模之后是负数,无法进行比较,所以先取正。
!判断是否倒转完,第16行,不能用位数,因为中断出来位数也减了1
直接倒转:
1 int reversemin(int x, int i, int ten) 2 { 3 int m = 0; 4 while (i--) { 5 int rest = x % 10; 6 m += rest * ten; 7 x /= 10; 8 ten /= 10; 9 } 10 return m; 11 }
整体代码:
1 class Solution { 2 public: 3 int reverse(int x) { 4 unsigned int y = x; 5 if(x<0) y=-x; 6 if(y>INT_MAX) return 0; 7 int reversemin(int x, int i, int ten); 8 int reversemax(int x,int i,int ten); 9 int m=x,i=1,ten=1; 10 while(m/=10){ ++i;ten*=10;} 11 if(i<10) m=reversemin(x,i,ten); 12 else m=reversemax(x,i,ten); 13 return m; 14 } 15 }; 16 int reversemin(int x, int i, int ten) 17 { 18 int m = 0; 19 while (i--) { 20 int rest = x % 10; 21 m += rest * ten; 22 x /= 10; 23 ten /= 10; 24 } 25 return m; 26 } 27 int reversemax(int x,int i,int ten) 28 { 29 int sign=1; 30 if(x<0) {x=-x; sign=-1;} 31 int m=0,max=INT_MAX; 32 while (i--) { 33 int rest = x % 10; 34 int mrest=max/ten; 35 if(rest>mrest) return 0; 36 else if(rest<mrest) break; 37 m += rest * ten; 38 x /= 10; 39 max=max-mrest*ten; 40 ten /= 10; 41 } 42 if(ten==0) return m*sign; 43 ++i; 44 45 while (i--) { 46 int rest = x % 10; 47 m += rest * ten; 48 x /= 10; 49 ten /= 10; 50 } 51 return m*sign; 52 53 }
@jm_epiphany
2019-03-23 新更新内容:之前一直没有看别人的解法,发现这样太过繁琐了,java中int是用补码表示的,当这个数超出范围时,他肯定和之前的码不一样了,判断不一样即可
1 public int reverse(int x) 2 { 3 int result = 0; 4 5 while (x != 0) 6 { 7 int tail = x % 10; 8 int newResult = result * 10 + tail; 9 if ((newResult - tail) / 10 != result) 10 { return 0; } 11 result = newResult; 12 x = x / 10; 13 } 14 15 return result; 16 }