LeetCode9-回文数

题目描述

判断一个整数是否是回文数。回文数是指 正序(从左向右)和倒序(从右向左)读都是一样的整数。

我的题解

不管什么方法,可以先把几种情况去掉:

  1. 负数
  2. 以0结尾的正数

解法1

先使用最笨的方法:转化为字符串,然后调用相关的reverse函数,最后比较

   //Java
    public boolean isPalindrome(int x) {
        if (x>=0){
            String tmp = Integer.toString(x);
            String revStr = new StringBuilder(tmp).reverse().toString();
            if (revStr.equals(tmp))return true;
        }
        return false;
    }

解法2

可以不使用内置的反转函数,自行判断。

   public boolean isPalindrome(int x) {
        if (x<0||x%10==0) return false;
        String str = Integer.toString(x);
        for (int i=0,j=str.length()-1;i<j;i++,j--){
            if (str.charAt(i)!=str.charAt(j))return false;
        }
        return true;
    }

这个解法也不是很好,因为还是在基于字符串的操作,这是既耗时,也耗空间,如何才能彻底摆脱字符串?

其他解法

把整个数字反转,然后和原数字比较是可行的,但是出现两个问题:

  1. 可能造成溢出。必须使用更宽的整数类型来存放反转的结果。
  2. 全部反转比较麻烦

于是考虑:只反转低位一半的数字,然后和另一半处理。
需要解决几个问题:

  1. 怎么实现反转?
    每次取出最低位,反转数乘以10以后加上去(原来的低位变为了高位:通过每次乘以10实现)
    考虑:123
    int res = 0;
    先取出最低位3,res = res * 10+3 = 3
    再取出2,res = 3 * 10+2 = 32
    最后取出1, res = 32 * 10+1 = 321
    于是实现了反转

  2. ‘一半’怎么判定,奇数位怎么办?

对于一个数,到底什么时候应该停止反转。
可以通过比较大小判断。
如果反转后的数 >= 剩余的数,则停止反转。
对于偶数: 反转过程中,若是回文,左右会出现相同而停止,如123321,反转一半后一定相同,所以才会有停止条件>=
若非回文,停止时不一定相同,如999111,反转为99,1111才会停止,而111999则会是111,999,但是这并不影响判断。
对于奇数:一定是反转的多一位才会停止,,中间这位不会影响回文判断,最后是反转数的最低位,去掉即可

根据上面的分析,有代码(java):

     public boolean isPalindrome(int x) {
        if (x<0 || (x!=0&&x%10==0)) return false;  //直接去掉不是回文的:负数,0结尾的正数
        int rev = 0;
        while(x>rev){
            rev = rev + x%10;
            x/=10;
        }
        return x==rev || x==rev/10;  //偶数、奇数情况
    }

彻底摆脱了字符串
性能比基于字符串的实现好:

  • 时间复杂度:O(log10(N)), 每次除10,时间复杂度^10 = N
  • 空间复杂度:O(1)
posted @ 2020-03-15 17:29  Edwin_Xu  阅读(108)  评论(0编辑  收藏  举报