不得不说这些天刷题还是有效果的,现在写程序已经有点感觉了,嘿嘿~加油!
先看第九题:
Determine whether an integer is a palindrome. Do this without extra space.
题目要求很简单,就是判断一个整数是不是回文的,和第五题有点类似,但是这题的难度明显简单了许多,且主要表现在额外要求上——本题要求不适用额外的空间,即空间复杂度为O(1)。这样的要求意味着像第五题一样利用额外数组储存整数各个数位上的数的想法被PASS了。但是这道题明显不需要把所有数字全输出再比较,于是我们可以想办法得到整数的首尾数进行比较,若相同继续比较次首和次尾,若不同直接输出非回文数即可。
具体做法:前些天写第倒置整数那题(第七题)就分析过,要求一个整数各个数位的数尽量直接对整数进行操作,使用整除和取余操作即可。尾数的获取自然想到除10取余即可,首数的获取怎么办呢?方法也很简单,先想办法获取整数的位数,再除10的(位数-1)次方即可。比较首尾数后如何比较次首和次尾的方法也很简单,为了降低时间复杂度,这里不采用递归的做法,而是利用循环去除首尾数,再重复上述判断过程即可,直至剩下一位数或0(偶数长度的整数)。
这里有个特别需要注意的地方,也是我第一次测试的时候没有考虑到的:如果去除首尾数后,原本在整数中间的0有可能会变成首0,这样在去除首尾数后会被自动剔除,导致剩余数字不再是对称分布的,这个情况需要重点考虑。解决方法也很简单,只需要对剩余数进行判断,如果的确去除了首0,加个判断剩余数末位是否也含有等量的0即可,如果没有则不是回文,否则继续判断。
最终,accepted的代码如下:
#include "stdafx.h"
#include <iostream>
#include <math.h>
using namespace std;
bool isPalindrome(int x) {
//负数不为回文数
if(x<0)return false;
int num = 0,ox = x;
while(ox!=0){ox/=10;num++;}
while(x/10!=0){
if((x%10)!=(x/(int)pow(10.0,num-1)))return false;
else {
x = x%(int)pow(10.0,num-1);
x/=10;
num = num - 2;
//这里要判断x是否去除了中间位数的0
ox = x;int c=0;
while(ox!=0){ox/=10;c++;}
//如果去除,再判断去除后的数后几位是不是也有等量的0,并去除
if(c!=num){
while(c!=num){
if(x%10==0){x/=10;num-=2;c--;}
else return false;
}
}
continue;
}
}
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
int x = 100110001;
bool b = isPalindrome(x);
if(b)cout<<x<<" is Palindrome"<<endl;
else cout<<x<<" is not Palindrome"<<endl;
return 0;
}
总结:
1.不需要额外空间就是说空间复杂度为O(1);
2.做过的题有很多思路和方法是可以互相借鉴的,要注意总结。