1.回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
例如,121 是回文,而 123 不是。
示例一:
示例二:
示例三:
2.转换为字符串并反转
第一眼看见这个问题,我的第一反应就是将数字x转换为字符串,然后将字符串反转,最后比较反转前后的字符串是否一致即可解决问题,但是这样的做法无疑于增加的额外的空间复杂度,但是编码实现更简单,具体代码如下所示:
class Solution {
public boolean isPalindrome(int x) {
// 先将数字转换为字符串,然后将字符串反转,比较反转后的字符串是否与原字符串相等
String new_str=new StringBuilder(x+"").reverse().toString();
return (x+"").equals(new_str);
}
}
运行结果如下所示:
由执行效果来看,效率确实很低,效果不好,不过编码实现更为简单,思路清晰。
3.反转一半数字
由于第一种方法效率太低,这里想办法对效率进行改进!
第二个想法是将数字本身反转,然后将反转后的数字与原始数字进行比较,如果它们是相同的,那么这个数字就是回文。
但是,如果反转后的数字大于 int.MAX,我们将遇到整数溢出问题。
那么,既然本题要求的是要求我们判断是否为回文数,那么我们就可以根据回文数的对称性反转一半的数字,如果是回文数,那么后半句部分反转后的数字必然把与前半部分相等!这就是我们题解的方法。
具体实现代码如下所示:
//如果x为负数 则一定不是回文数
//如果x的个位数是0,且x不是0,也一定不是回文数(例如10,20)
if(x<0 ||(x%10==0 && x!=0))
return false;
//接下来反转一半的数字
int reverseNum=0;
while(reverseNum<x){
reverseNum=reverseNum*10+x%10;
x/=10;
}
return (x==reverseNum) || (reverseNum/10==x);
执行效率如下所示:
可以看到,改进后的方法比第一种方法效率确实提高了,但是这种实现思路需要一定的数学逻辑思维。
2.最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
示例一:
示例二:
这里仅仅给出暴力求解的办法,具体有关动态规划与中心扩展算法的解法可自行去查阅资料求解!
面对此题,我们可以按顺序依次截取字符串s的子串,判断此子串是否为回文子串,若满足回文特征,判断其长度是否大于当前最长回文长度max,若大于max,则依次修改回文子串的结果result以及回文子串的最大长度max。
这里需要注意: 采用二层循环遍历子串的时候,如果j-i<=max,则没有判断回文的必要,只有 当j-i>max,且满足最长回文的要求,我们才对max和result做相应的修改! 这里相当于是对暴力法做一定程度上的剪枝,做一点优化。具体代码如下所示:
class Solution {
// 判断是否为回文字符串
public boolean isHuiwen(String s) {
int len = s.length();
for (int i = 0; i < len/2; i++) {
if(s.charAt(i)!=s.charAt(len-1-i))
return false;
}
return true;
}
public String longestPalindrome(String s) {
int max=0;//记录最长回文子串
String result="";//记录最长回文子串的结果
for(int i=0;i<s.length();i++){
for(int j=i+1;j<=s.length();j++){
if((j-i)>max){//判断j-i可以减少一定量的判断
String subStr=s.substring(i,j);
if(isHuiwen(subStr) && subStr.length()>max){
max=subStr.length();
result=subStr;
}
}
}
}
return result;
}
}