125. 验证回文串 - 力扣(LeetCode)
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
示例 1:
输入: s = "A man, a plan, a canal: Panama"
输出: true
解释: "amanaplanacanalpanama" 是回文串。
示例 2:
输入: s = " "
输出: true
解释: 在移除非字母数字字符之后,s 是一个空字符串 "" 。
由于空字符串正着反着读都一样,所以是回文串。
提示:
1 <= s.length <= 2 * 105s仅由可打印的 ASCII 字符组成
题解1:去除无效值 + 判断
由题意可知我们只需要验证: 将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读是否一样. 那么需要完成以下两步:
- 处理字符串,将字母都转为小写(或大写),并且仅保留字母和数字
- 比较新字符串和反转后的字符串是否相等
/**
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function(s) {
// 大写字母都转为小写字母
s = s.toLocaleLowerCase()
// 存放处理后的字符串
let str = ''
for(let i = 0; i < s.length; i++) {
// 判断是否为字母 (s[i] >= 'a' && s[i] <= 'z')
// 判断是为数字 s[i] !=' ' && !isNaN(s[i])
// 其中 isNaN(' ') 为false,所以需要额外排除掉空格
if((s[i] >= 'a' && s[i] <= 'z') || (s[i] !=' ' && !isNaN(s[i]))) {
str += s[i]
}
}
//
return str == str.split("").reverse().join("")
};
题解2: 双指针
设置两个指针i,j分别指向字符串首尾, i < j时进行遍历比较:
- 如果两个指针都指向字母数字元素且相等,指针更新继续遍历,不相等则返回false;
- 如果指针指向元素为非字母数字,指针指向非字母数字的指针更新,跳过无效元素;
- 遍历结束时函数还没return,则说明字符串为回文串,返回true
/**
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function(s) {
s = s.toLocaleLowerCase()
let i = 0
let j = s.length
while(i < j) {
// 两个指针均指向有效元素,即字母、数字
if(judge(s[i]) && judge(s[j])) {
// 相等,继续遍历
if(s[i] == s[j]) {
i++
j--
continue
} else {
// 不相等则不是回文串,返回false
return false
}
}
// 指针指向无效值,指针更新
if(!judge(s[i])) {
i++
}
if(!judge(s[j])) {
j--
}
}
return true
};
// 判断元素是否为字母或数字
function judge(val) {
return (val >= 'a' && val <= 'z') || (val != ' ' && !isNaN(val))
}