面试题算法分析(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("是回文\n");
break;
}
}else if(*head != *tail)
{
printf("不是回文\n");
break;
}
}
}