思路
- 首先枚举出字母和数字(orz…看了其他人的题解, 才想起来
Character.isLetterOrDigit
可以直接判断字符串是否字母或数字); - 声明左指针指向入参第0位, 右指针指向入参最后一位, 用于判断左指针指向的元素(简称左元素)是否等于右指针指向的元素(简称右元素), 每遍历一次都会让左右指针往中间靠拢;
- 当左元素不是合法字符时, 左指针循环后移一位, 直到找到下一个合法字符; 右指针同理, 期间左指针不能超过右指针, 否则会下标越界/重复判断;
- 如果左指针和右指针已经指向同一位, 说明其他下标的元素都已相等;
- 使用字符串的api, 忽略大小写判断左元素和右元素是否相等, 如果不相等则直接返回false。
代码
class Solution {
public boolean isPalindrome(String s) {
// 忘记正则了, 枚举出所有字母和数值, 并转换为Set, 便于后续判断时间复杂度降为O(1)
final String charStr = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890";
int left = 0;
int right = s.length() - 1;
Set<Character> cs = new HashSet<>();
for (int i = 0; i < charStr.length(); i++) {
cs.add(charStr.charAt(i));
}
while (left < right) {
// 左指针不是字母或数字, left < right条件避免下标越界
while (!cs.contains(s.charAt(left)) && left < right) {
left++;
}
// 右指针不是字母或数字
while (!cs.contains(s.charAt(right)) && left < right) {
right--;
}
// 如果已经减到超出了左右指针各自的范围, 说明前面的比较都通过了, 退出循环即可
if (right == left) {
break;
}
// 判断元素是否相等
if (!String.valueOf(s.charAt(left)).equalsIgnoreCase(String.valueOf(s.charAt(right)))) {
return false;
}
left++;
right--;
}
return true;
}
}
题目链接
125. 验证回文串