思路
- 首先枚举出字母和数字(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. 验证回文串