题目及用例
package pid007;
/* 颠倒整数
给定一个 32 位有符号整数,将整数中的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。根据这个假设,如果反转后的整数溢出,则返回 0。
*/
public class main {
public static void main(String[] args) {
int[] testTable = {123,-2561,1340,1534236469};
for (int i=0;i<testTable.length;i++) {
test(testTable[i]);
}
}
private static void test(int ito) {
Solution solution = new Solution();
int rtn;
long begin = System.currentTimeMillis();
System.out.print(ito+" ");
System.out.println();
rtn = solution.reverse(ito);//执行程序
long end = System.currentTimeMillis();
System.out.print(rtn+" ");
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
解法一(失败)
用测试用例时成功,leetcode检验失败,因为传入超出int类型的参数
思路是先判断正负,再去掉负号,正负统一处理,转为char数组头尾颠倒,最后加上负号转为int,就是过大不能转为int
public int reverse(int x) {
String num;
boolean isPositive;
int length;
if(x<0){
isPositive=false;
num=String.valueOf(-x);
length=num.length();
}
else{
isPositive=true;
num=String.valueOf(x);
length=num.length();
}
if(length==0||length>32){
return 0;
}
//变为char数组互换
char[] nums=num.toCharArray();
char temp;
int i=0;
int j=length-1;
while(i<j){
temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
i++;
j--;
}
num=new String(nums);
int result;
if(isPositive){
result=Integer.valueOf(num.trim());
}
else{
result=Integer.valueOf(num.trim())*-1;
}
return result;
}
解法2(失败)
发现1的失败是因为输入的int在int范围内,而反转后不再范围内,导致抛出错误。
此方法现将数字转为long,再判断是否在int范围内,再转为int,但是最后超出时间范围
package pid007;
public class Solution {
public int reverse(int x) {
String num;
boolean isPositive;
int length;
if(x<0){
isPositive=false;
num=String.valueOf(-x);
length=num.length();
}
else{
isPositive=true;
num=String.valueOf(x);
length=num.length();
}
if(length==0){
return 0;
}
//变为char数组互换
char[] nums=num.toCharArray();
char temp;
int i=0;
int j=length-1;
while(i<j){
temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
i++;
j--;
}
num=new String(nums);
long result;
if(isPositive){
result=Long.valueOf(num);
}
else{
result=Long.valueOf(num)*-1;
}
if(result<Math.pow(2,31)-1&&result>-Math.pow(2, 31)){
return (int)result;
}
else{
return 0;
}
}
}
解法三(成功,112ms,特别慢)
发现前面出错的原因是num=String.valueOf(-(long)(x)); 这里如果没有long,乘以副一貌似因为溢出无效,到处还有-号,从而最后出错
public int reverse(int x) {
String num;
boolean isPositive;
int length;
if(x<0){
isPositive=false;
num=String.valueOf(-(long)(x));
length=num.length();
System.out.println(num);
}
else{
isPositive=true;
num=String.valueOf((long)x);
length=num.length();
}
if(length==0){
return 0;
}
//变为char数组互换
char[] nums=num.toCharArray();
char temp;
int i=0;
int j=length-1;
while(i<j){
temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
i++;
j--;
}
num=new String(nums);
long result;
if(isPositive){
result=Long.valueOf(num);
}
else{
result=(Long.valueOf(num))*-1;
}
if(result<Math.pow(2,31)-1&&result>-Math.pow(2, 31)){
return (int)result;
}
else{
return 0;
}
}
解法三(成功,10ms,较慢)
先确定sign
然后int变成string变成char数组,然后颠倒,然后变成string,变成long,进行检验,检验通过后变成int乘以sign
public int reverse(int x) {
int sign=1;
if(x<0){
//先设置符号位,最后结果乘以sign
sign=-1;
}
//num为无符号的整数对于的char数组,在其中反转
if(x==Integer.MIN_VALUE){
//这个为特殊情况,*-1后大于max,错误
return 0;
}
char[] num=String.valueOf(x*sign).toCharArray();
for(int i=0;i<num.length/2;i++){
num[i]=(char) (num[i]^num[num.length-1-i]);
num[num.length-1-i]=(char) (num[i]^num[num.length-1-i]);
num[i]=(char) (num[i]^num[num.length-1-i]);
}
String resultString=String.valueOf(num);
Long resultLong=Long.valueOf(resultString);
//如果结果大于max,则返回0
if(resultLong>Integer.MAX_VALUE){
return 0;
}
return Integer.valueOf(resultString)*sign;
}
解法4(别人的)
本题如果不考虑溢出问题,是非常简单的。解决溢出问题有两个思路,第一个思路是通过字符串转换加try catch的方式来解决,第二个思路就是通过数学计算来解决。
由于字符串转换的效率较低且使用较多库函数,所以解题方案不考虑该方法,而是通过数学计算来解决。
通过循环将数字x的每一位拆开,在计算新值时每一步都判断是否溢出。
溢出条件有两个,一个是大于整数最大值MAX_VALUE,另一个是小于整数最小值MIN_VALUE,设当前计算结果为ans,下一位为pop。
从ans * 10 + pop > MAX_VALUE这个溢出条件来看
当出现 ans > MAX_VALUE / 10 且 还有pop需要添加 时,则一定溢出
当出现 ans == MAX_VALUE / 10 且 pop > 7 时,则一定溢出,7是2^31 - 1的个位数
从ans * 10 + pop < MIN_VALUE这个溢出条件来看
当出现 ans < MIN_VALUE / 10 且 还有pop需要添加 时,则一定溢出
当出现 ans == MAX_VALUE / 10 且 pop < -8 时,则一定溢出,8是-2^31的个位数
class Solution {
public int reverse(int x) {
int ans = 0;
while (x != 0) {
int pop = x % 10;
if (ans > Integer.MAX_VALUE / 10 || (ans == Integer.MAX_VALUE / 10 && pop > 7))
return 0;
if (ans < Integer.MIN_VALUE / 10 || (ans == Integer.MIN_VALUE / 10 && pop < -8))
return 0;
ans = ans * 10 + pop;
x /= 10;
}
return ans;
}
}