Java萌新闯力扣:7.整数反转

          力扣热题:7.整数反转

一、开篇

 这道题把我坑的好苦,看起来很简单,结果写了一个多小时,被自己菜傻了。我还很懒,不肯去debug,写到后面熬不住了,才去debug发现了问题。兄弟们写题一定要善用debug,不然会和我一样花好长时间。

二、题目链接:7.整数反转

三、题目描述Java萌新闯力扣:7.整数反转_第1张图片

四、代码思路

1.根据题目,考虑用List有序集合来保存原来整数的每一位,然后再将其从0号索引位输出出来
2.对于正负数的情况,可以用一个变量标记一下,然后把负号去掉
3.在用list集合存好每一位后,用while循环输出反转的每一位,对每一位进行判断,如果加上这一位会超出范围,则返回0;否则,用一个整数变量存起来
4.最后把整数返回

五、涉及的算法及知识点

1.对list集合对创建及相关方法,add():添加元素;get():获取元素;remove():移除元素
2.Math类中去绝对值的abs()方法,注意边界情况,第八点踩坑有提及
3.对int取值范围的理解,以及面对比int范围大的数,可以考虑用long类型
4.如何在循环中逐位添加数

六、代码纯享版

class Solution {
    public int reverse(int x) {
        List<Integer> list = new ArrayList<>();
        int judge = 1;
        if (x < 0) {
            judge = 0;
            x = Math.abs(x);
        }
        if(x<0) return 0;
        while (x != 0) {
            list.add(x % 10);
            x /= 10;
        }
        long num = 0;
        while (list.size() > 0) {
            if (judge == 1 && (num * 10 + list.get(0)) > Math.pow(2, 31)) return 0;
            if (judge == 0 && (num * (-10) - list.get(0)) < Math.pow(-2, 31)) return 0;
            
            num = (num * 10 + list.get(0));
            list.remove(0);
        }
        if (judge == 1) return (int) num;
        return (int) num * (-1);
    }
}

七、代码逐行解析版

class Solution {
    public int reverse(int x) {
        List<Integer> list = new ArrayList<>(); //创建有序集合,来存储整数的每一位
        int judge = 1; //judge用来判断x是正数还是负数,1是正数,0是负数
        if (x < 0) {  //x是负数时,改变judge,同时取x的绝对值,方便list的存储
            judge = 0;
            x = Math.abs(x);
        }
        if(x<0) return 0; //如果abs无法将x变成正数,证明x=-2^31(-2147483648),反转过来也是超出范围,直接返回0
        while (x != 0) { //利用while循环从个位起把整数的每一位存到list里
            list.add(x % 10); //利用取模运算提取最小的一位
            x /= 10; //利用除法去掉最小的一位
        }
        long num = 0; //num用来记录反转后的整数,注意要用long,如果用int,下面while循环中,前两个if的判断条件会发生错误
        while (list.size() > 0) { //利用while循环来把list集合的每一位取出
            if (judge == 1 && (num * 10 + list.get(0)) > Math.pow(2, 31)-1) return 0; //当x为正数且反转后的整数大于2^31-1,返回0
            if (judge == 0 && (num * (-10) - list.get(0)) < Math.pow(-2, 31)) return 0; //当x为负数且反转后的整数小于-2^31,返回0

            num = (num * 10 + list.get(0)); //把之前存过的数乘10,再把本次的数存在个位
            list.remove(0); //记住把存过的数从list集合中移除

        }
        if (judge == 1) return (int) num;  //根据正负数分情况把num返回,注意用把long类型转为int型
        return (int) num * (-1);
    }
}

八、踩坑

1.取模运算可以取负数,这是我这道题最惨痛的教训,如果没有遗漏这个知识点,就不会有后面的错误。如果我知道取模运算可以取负数,那就可以考虑用int来解决问题(参考下面大佬代码)
2.Math.abs(pow(-2,31)) == pow(-2,31):在利用abs取绝对值时,由于int的范围是[-2^31, 2^31 -1],所以当题目的测试用例是-2 ^31 时,无法用abs把它化成 2^31 ,而是仍然等于 -2^31
3.当int类的数在加减乘除时,整体超过了int范围,即使没有将其赋值,仍会计算错误
例:num * 10 + list.get(0)> Math.pow(2, 31)-1,假设num初始时int型,当num * 10 + list.get(0)超过了int范围,虽然num的值本身没改变,但num * 10 + list.get(0)计算出来的结果是错误的,所以在代码中我用了long num而不是int num

九、大佬代码

思路:直接用int类型的变量来保存反转整数,更加方便,且仅用一个循环体,时间复杂度超低,对边界值的判断很显功力,我自己做题想不出来,看完直接五体投地

class Solution {
    public int reverse(int x) {
        int res = 0;
        while(x!=0) {
            //每次取末尾数字
            int tmp = x%10;
            //判断是否 大于 最大32位整数
            if (res>214748364 || (res==214748364 && tmp>7)) {
                return 0;
            }
            //判断是否 小于 最小32位整数
            if (res<-214748364 || (res==-214748364 && tmp<-8)) {
                return 0;
            }
            res = res*10 + tmp;
            x /= 10;
        }
        return res;
    }
}	

十、结语

  通过这篇文章,希望大家对反转整数这道题有更深入对了解,避免和我一样踩坑无数。如果有什么建议和评价请发在评论区,感谢大家对阅读。

你可能感兴趣的:(Java算法,java,leetcode,开发语言,算法)