LeetCode小白菜笔记[3]:Palindrome Number

LeetCode小白菜笔记[3]:Palindrome Number

9. Palindrome Number [Easy]

题目:Determine whether an integer is a palindrome. Do this without extra space.

click to show spoilers.
Some hints:
Could negative integers be palindromes? (ie, -1)
If you are thinking of converting the integer to string, note the restriction of using extra space.
You could also try reversing an integer. However, if you have solved the problem “Reverse Integer”, you know that the reversed integer might overflow. How would you handle such case?
There is a more generic way of solving this problem.

首先,负数直接判False,另外,整数的首位数字不能是0,故尾数为0的直接判False,当然0本身是一个trivial的回文数。
下面对于普遍的情况进行判断,最先想到的直接的方法就是每一位和对应的高位数字比较,如果有不一样,return False,否则判True。代码如下:

class Solution(object):
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        if (x<0 or (x % 10 == 0 and not x == 0)): # tackle trivial ones
            return False
        length = 1
        while(not x % (10 ** length)==0):
            length = length + 1
        for i in range( length // 2 ):
            if (not x // (10 ** i) % 10 == x // (10 ** (length-1-i)) % 10):
                return False
        return True

结果不出意外的G了G。。。

这里写图片描述

超时了。。。目测是太多乘幂运算了,占用了很多时间,而且每次取一位比较,这样的取法也是不太科学,很暴力。因此考虑其他的思路。翻转后再比较是一个可行的思路,但是会有overflow问题。考虑到实际上比较回文并不一定需要完全翻转和原数比较,可以翻转后一半和前面一半比较。这样可以避免溢出。代码如下:

class Solution(object):
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        if (x<0 or (x % 10 == 0 and not x == 0)): # tackle trivial ones
            return False
        length = 1
        while(not x % (10 ** length) == 0):
            length = length + 1
        length = length // 2
        half_reversed = 0
        for i in range(length):
            half_reversed = half_reversed * 10 + x % 10
            x = x // 10
        return (x == half_reversed or x // 10 == half_reversed)

鹅毛妈妈么么萌。。。还是 time limit exceeded,看来这个求length,即位数长度的这个乘幂也不能要。那该怎么判断是否到了中点呢?考虑长度为单数和双数的回文,如1235321,和124421,我们希望翻转成1235 123以及 124 124,如果从低到高,到了中点后再继续翻转一位,那么,123 1235,以及12 1244,翻转的一半会比前面的长,由于我们已经将尾数为0的直接判False了,所以位数长一定数值要大,所以可以用翻转后的大于剩下的部分作为退出循环的条件。试一试:

class Solution(object):
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        if (x<0 or (x % 10 == 0 and not x == 0)): # tackle trivial ones
            return False
        half_reversed = 0
        while(x > half_reversed): 
            half_reversed = half_reversed * 10 + x % 10
            x = x // 10
        return (x == half_reversed or x == half_reversed // 10)

这个while的判别条件用的剩下的大于翻转的,这样如果是124 124,那么就不进去,而1235 123 最后一次进去,变成123 1235,因此half_reversed要除以10和剩余的比较。

终于通过了。。。

这里写图片描述

总结
注意每次应用之前循环的结果,每一位模和取位数这样的操作应避免,因为涉及到乘幂。感觉貌似理解起来简单而且写起来很直接的代码往往都run不过……
注意关注输入本身特性。

THE END

星期日, 10. 十二月 2017 06:40下午

posted @ 2017-12-10 18:42  毛利小九郎  阅读(75)  评论(0编辑  收藏  举报