不使用额外空间,检查整数是否是回文结构

Question: Given an Integer, you need to determine if it is a palindrome or not. You should not use any extra space in the process.
Input: 121
Output: Palindrome

咋一看问题很简单,我们只要镜像翻转这个数看是否和原来的数一样。但是这题的要求有个不使用额外空间的限制,我们还要考虑到语言和环境的差异,给出一个一般化的方法。

题目并没有说是否要考虑负数的情况,比如-1是不是回文结构呢?作为编程人员要考虑到所有的可能性。为了讨论的便利性,这里我们先把他们排除出去。

考虑到字符串更好操作,可能要将整数转换成字符串。但这也会使用额外空间来放置翻转后的字符(例如,整数有n位,那么你至少要多分配n位用于存储字符串,C语言中通常还要多分配一位)。看起来这题有点强人所难(就是用了额外空间也用不到多少),但面试题通常都是这个风格。

另一个方法就是翻转数字再和原来的数字比较。如果相同就是回文结构的。可以这样做:

int reverse(int num)
{
    assert(num >= 0);   // for non-negative integers only.
    int rev = 0;
    while (num != 0)
    {
        rev = rev * 10 + num % 10;
        num /= 10;
    }
    return rev;
}

看起来解决了问题,但你考虑到了溢出问题吗?(例如unsigned int i=198,翻转后因该是891,实际上超出了表示范围),溢出后的程序动作取决于使用的语言。

当然我们可以使用比int类型大的类型(如long long)来存储和返回数据。但这样的类型大小和语言、机器有关。大的数据类型不是所有语言都支持。

我们可以设计一个更通用的程序。重点是,我们肯定要能够在某个时刻开始比较第一个数字的最后一个数字。可以从中间开始往两边比较,也可以从两边开始。

看起来从两边开始容易点。首先,比较第一个数和最后一个数,如果他们不同,肯定不是回文结构,如果相同,砍掉他们继续比较直到没有数字剩下,那么他肯定就是回文结构了。

砍掉最后一位数比较容易,砍掉最前面一位数就要稍微思考一下了。下面是完成代码,有兴趣的同学可以用main函数测试一下:

int isIntPalindrome(int x)
{
    if (x < 0)
    return 0;
    int div = 1;
    while (x / div >= 10)
    {
        div *= 10;
    }
 
    while (x != 0)
    {
        int l = x / div;
        int r = x % 10;
        if (l != r)
            return 0;
        x = (x % div) / 10;
        div /= 100;
    }
    return 1;
}
posted @ 2015-07-31 10:34  programnote  阅读(880)  评论(0编辑  收藏  举报