leetcode初级算法题解JavaScript 125.验证回文串

88 阅读2分钟

125. 验证回文串 - 力扣(LeetCode)

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false

示例 1:

输入: s = "A man, a plan, a canal: Panama"
输出: true
解释: "amanaplanacanalpanama" 是回文串。

示例 2:

输入: s = " "
输出: true
解释: 在移除非字母数字字符之后,s 是一个空字符串 "" 。
由于空字符串正着反着读都一样,所以是回文串。

提示:

  • 1 <= s.length <= 2 * 105
  • s 仅由可打印的 ASCII 字符组成

题解1:去除无效值 + 判断

由题意可知我们只需要验证: 将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读是否一样. 那么需要完成以下两步:

  1. 处理字符串,将字母都转为小写(或大写),并且仅保留字母和数字
  2. 比较新字符串和反转后的字符串是否相等
/** 
* @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("") 
 };

image.png

题解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))
}

image.png