「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。
题目
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: "A man, a plan, a canal: Panama"
输出: true
解释:"amanaplanacanalpanama" 是回文串
示例 2:
输入: "race a car"
输出: false
解释:"raceacar" 不是回文串
提示:
- 1 <= s.length <= 2 * 105
- 字符串 s 由 ASCII 字符组成
解答思路
双指针
- 定义两个指针,一个指针从前向后移动;另外一个指针从后向前移动;
- 如果两个指针指向的字符相同,则同时移动再判断它们指向的下一个字符是否相同;这样一直移动直到两个指针相遇
细节点
1、如果某个指针指向的字符既不是字母又不是数字,则移动指针跳过该字符
2、由于题目要求忽略大小写,因此需要把所有的字母都转换成小写形式(或同时转换成大写形式)进行比较
/**
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function(s) {
let i = 0,
j = s.length - 1;
// 是否是数字或字母
const isLetterOrDigit = (code) => {
if (
// 大写字母
(code >= 97 && code <= 122) ||
// 小写字母
(code >= 65 && code <= 90) ||
// 数字
(code >= 48 && code <= 57)
) {
return true;
}
return false;
};
while (i < j) {
let ch1 = s.charCodeAt(i),
ch2 = s.charCodeAt(j);
if (!isLetterOrDigit(ch1)) {
i++;
} else if (!isLetterOrDigit(ch2)) {
j--;
} else {
// 两个指针所指向的内容都是字母或数字
ch1 = s[i].toLowerCase();
ch2 = s[j].toLowerCase();
// 题目要求的是忽略字母的大小写
if (ch1 != ch2) {
return false;
}
i++;
j--;
}
}
return true;
};
用正则表达式优化代码如下:
var isPalindrome = function (s) {
s = s.replace(/[\W|_]/g, "").toLowerCase();
if (s.length < 2) {
return true;
}
let left = 0;
let right = s.length - 1;
while (left < right) {
if (s[left] !== s[right]) {//对撞指针判断左右两边是否是相同的字符
return false;
}
left++;
right--;
}
return true;
};
结束语
这里是小葵🌻,只要把心朝着太阳的地方,就会有温暖~
让我们一起来攻克算法难关吧!!