面试题算法分析(2)

判断一个数字是不是回文数字
分析:由于题目已经要求不能使用额外空间,故不可以把数字转换为字符串s,然后对s取反得到s',判断两字符串是否相等。解决方案是用循环直接将数字取反,最后将得到的新数字与原始数字比较。

public class Solution {
    public boolean isPalindrome(int x) {
        int a = x, r = 0;

        if (x < 0) return false;

        while (a > 0) {
            r = r*10 + a%10;
            a = a / 10;
        }
        
        return r == x;
    }
}

提交了,也通过了。但似乎总感觉有点问题,什么问题呢?上述方案没有考虑翻转后的数字溢出的问题,当r*10大于2^31-1时,截断其高位很可能会得到一个跟原始x接近的值,再加上a%10就刚好等于原始x了。(当然这只是一种顾虑,估计即便暴搜后也不见得能找到符合条件的数字)。如果题目再加一条约束说:不允许计算中出现溢出呢?

我们知道对于任意n位的数字,取n=5,数字95349为例

95349 % 10 => 9
95349 / 10000 => 95349 / 10^4 => 9

可以看出我们可以通过模10来取其最低位,除10^(n-1)来取其最高位,将其最高位和最低位进行比较,便可以得出当前是否符合回文要求了。

比较完最高位和最低位后,如何除掉这两位呢?
如此一来,便完成了掐头去尾了。

完整代码:

95349 % 1000 => 95349 % 10^4 = 5349
95349 / 10 = 9534
public class Solution {
    public boolean isPalindrome(int x) {
        int a = x, h = 1;

        if (a < 0) return false;

        while (a / h >= 10) {
            h = h * 10;
        }

        while (a > 0) {
            if (a / h != a % 10) return false;
            a = a % h;
            a = a / 10;
            h = h / 100;
        }

        return true;
    }
}

更一般的,我们判断一个字符串是不是回文字符串
详细代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void isPali_Number(char *head);

int main(int argc, char *argv[])
{
    char str[] = "abcddcba";
    isPali_Number(str);
    return 0;
}

void isPali_Number(char *head)
{
    char *tail;
    tail = head;
    while(*tail !=0)
    {
        tail++;   //将回文字符遍历一遍找到该字符的尾指针
    }
    tail--;
    while(head <= tail)
    {
        if(*head == *tail)
        {//head ->     <-tail
            head++;
            tail--;
            if((head + 1 == tail) || (head == tail)) //考虑奇偶数的情况
            {
                printf("是回文
");
                break;
            }
        }else if(*head != *tail)
        {
            printf("不是回文
");
            break;
        }
    }
}
原文地址:https://www.cnblogs.com/stardujie89/p/4079746.html