题目
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
解法一:双指针
我们先定义两个指针,一个指头,一个指尾。为了避免大小写比较造成的不便,就使用String的toLowerCase方法提前将字符串转成小写。接下来我们需要判断字符是否是字母或数字了。给你你会怎么判断?反正我就会一个条件表达式然后通过ASCII码判断。但是!!!谁曾想竟然有直接判断是否是字母或数字的API,而且还“人如其名”,就叫isLetterOrDigit(),下面我们来拓展一下
Character类:
- static boolean isLetterOrDigit(char ch)判断字符是不是字母或数字
- static boolean isLetter(char ch)判断字符是不是字母
- static boolean isDigit(char ch)判断字符是不是数字
class Solution {
public boolean isPalindrome(String s) {
int head = 0;
int tail = s.length()-1;
String str = s.toLowerCase();
while(head < tail){
char h = str.charAt(head);
char t = str.charAt(tail);
if(!Character.isLetterOrDigit(h)){
head++;
continue;
}
if(!Character.isLetterOrDigit(t)){
tail--;
continue;
}
if(h != t){
return false;
}
else{
head++;
tail--;
}
}
return true;
}
}
解法二:正则表达式
来源:力扣(LeetCode)
作者:数据结构和算法
链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xne8id/?discussion=BHK3ga
这是leecode里一位大佬发布的题解,但他所使用的正则表达式我却闻所未闻。我经过资料的查阅简单整理在这篇博客中,不了解的可以简单了解一下:http://t.csdn.cn/JSajl
所以这道题可以先将其它字符用replaceAll方法去掉,然后转换为小写字符串。通过调用StringBuffer的reverse()方法将字符串转换,再用String的equals()方法进行比较。
public boolean isPalindrome(String s) {
String actual = s.replaceAll("[^A-Za-z0-9]", "").toLowerCase();
String rev = new StringBuffer(actual).reverse().toString();
return actual.equals(rev);
}
虽然这则代码看起来只有短短三行,非常简单。但由于其全部都是通过API来实现,调用层数太多且底层也没有任何的简化,只是写起来方便一些,所以时间和空间开销比较大,不建议使用,我们主要通过这则代码来了解相关API的使用就好。