leetcode-7-反转整数(reverse integer)-java

题目及用例

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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值