LeetCode:125. 验证回文串 - JavaScript 解决方案 🚀

104 阅读2分钟

https___dev-to-uploads.s3.amazonaws.com_uploads_articles_a64yvq0wgnzm4l14yajo.gif

🚀 问题描述

如果一个短语在:

  • 将所有大写字母转换为小写。
  • 删除所有非字母数字字符后。

该短语正读和反读相同,则它是回文的。

如果输入字符串 s 是回文的,则返回 true;否则,返回 false

💡 示例

示例 1

输入:s = "A man, a plan, a canal: Panama"
输出:true
解释:清理后,"amanaplanacanalpanama" 正读和反读相同。

示例 2

输入:s = "race a car"
输出:false
解释:清理后,"raceacar" 不是回文。

示例 3

输入:s = " "
输出:true
解释:清理后,字符串为空,被认为是回文。

🏆 JavaScript 解决方案

我们可以使用双指针方法来检查清理后的字符串是否是回文。

实现代码

var isPalindrome = function(s) {
    let left = 0;
    let right = s.length - 1;

    while (left < right) {
        while (left < right && !isAlphanumeric(s[left])) left++;
        while (left < right && !isAlphanumeric(s[right])) right--;
        
        console.log('left', left)
        console.log('right', right)

        if (s[left].toLowerCase() !== s[right].toLowerCase()) {
            return false;
        }

        left++;
        right--;
    }

    return true;
};

function isAlphanumeric(char) {
    return /^[a-zA-Z0-9]$/.test(char);
}

console.log(isPalindrome("A man, a plan, a canal: Panama"))

🔍 工作原理

  1. 双指针
    • 从字符串的开头(left)和结尾(right)开始设置指针。
    • 将指针向中间移动。
  1. 跳过非字母数字字符
    • 使用函数 isAlphanumeric() 来确定有效字符。
    • 通过移动指针跳过无效字符。
  1. 比较字符
    • 使用 toLowerCase() 将两个字符都转换为小写后再进行比较。
    • 如果字符不匹配,返回 false
  1. 检查所有字符
    • 如果循环完成而没有不匹配的情况,返回 true

🔑 复杂度分析

  • 时间复杂度O(n),其中 n 是字符串的长度。
    • 每个字符都会被双指针处理一次。
  • 空间复杂度O(1),因为没有使用额外的数据结构。

📋 运行示例

输入:"A man, a plan, a canal: Panama"

输出:true

替代解决方案:清理并反转

另一种方法是清理字符串并检查它是否与其反转后的字符串匹配。

var isPalindrome = function(s) {
    const cleaned = s.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
    return cleaned === cleaned.split('').reverse().join('');
};

复杂度:

  • 时间复杂度:O(n),用于清理、反转和比较字符串。
  • 空间复杂度:O(n),用于清理后的字符串和反转后的字符串。

✨ 面试技巧

  1. 处理边界情况
    • 空字符串("")→ true
    • 只包含非字母数字的字符串(例如,"!!")→ true
  1. 效率
    • 双指针方法在空间上更高效。
    • 清理和反转的方法更简单,但使用了更多内存。
  1. 解释辅助函数
    • 讨论为什么使用基于正则表达式的 isAlphanumeric() 是清晰且有效的。

原文:dev.to/rahulgithub…