【算法】字符串:验证回文串 |【掘金日新计划·12月更文挑战】

71 阅读2分钟

题目:验证回文串

leetcode链接:验证回文串

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

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

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

理解:

1、什么是回文串?简单理解就是正着读和反着读都是一样内容的字符串,形如:上海自来水来自海上,不管是从左到右看还是从右到左看,得到的信息是一样的。

具体条件特征如下:

1、统一字符格式:字符全部转化为小写

2、排除干扰项:移除全部非字母和数字的字符

3、顺序或者倒序看得到相同的字符串

思路:

1、正则:过滤掉非字母和数字的字符,然后倒序输出字符串存至临时变量,最后比较临时变量的字符串和原字符串是否相等即可。

2、双指针:左右指针一前一后相向遍历,碰到非字母和数字的字符直接略过,然后比较前后两个字符时候相同,若不相同直接返回false,否则,最终返回true

3、双指针 + 递归:利用双指针过滤掉非字母和数字的字符,然后使用递归判断左右指针字符是否相等

4、正则 + 双指针:先用正则过滤掉非字母和数字的字符,然后利用双指针判断左右指针字符是否相等,返回true或者false

题解:

方案一:正则

/**
 * @param {string} s
 * @return {boolean}
 */
var isPalindrome = function(s) {
    // 过滤掉非字母和数字的字符
    s = s.replaceAll(/[^0-9a-zA-Z]/g, '').toLowerCase()
    let reverseStr = ''
    // 遍历及倒序输出字符串形成新串
    for (let i = s.length - 1; i >= 0; i--) {
        reverseStr += s[i].toLowerCase()
    }
    // 比较新旧字符串是否相等
    return s === reverseStr
};

image.png

方案二:双指针

/**
 * @param {string} s
 * @return {boolean}
 */
var isPalindrome = function(s) {
    if (!s || !s.length) return true;
    s = s.toLowerCase();
    for (let left = 0, right = s.length - 1; left < right; left++, right--) {
        // 左指针-过滤掉非字母和数字的字符
        while (left < right && !/[0-9a-zA-Z]/.test(s[left])) {
            left++;
        }
        // 右指针-过滤掉非字母和数字的字符
        while (left < right && !/[0-9a-zA-Z]/.test(s[right])) {
            right--;
        }
        if (s[left] != s[right]) return false;
    }
    return true;
};

image.png

方案三:双指针 + 递归

/**
 * @param {string} s
 * @return {boolean}
 */
var isPalindrome = function(s) {
    return isPalindromeHelper(s, 0, s.length - 1);
};

var isPalindromeHelper = function (s, left, right) {
        if (left >= right) return true;
        while (left < right && !/[0-9a-zA-Z]/.test(s[left]))
            left++;
        while (left < right && !/[0-9a-zA-Z]/.test(s[right]))
            right--;
        return s[left].toLowerCase() == s[right].toLowerCase() && isPalindromeHelper(s, ++left, --right);
}

image.png

方案四:正则 + 双指针

/**
 * @param {string} s
 * @return {boolean}
 */
var isPalindrome = function(s) {
    var s1 = s.replace(/[^A-Za-z0-9]/g, '').toLowerCase();
    for (let left = 0, right = s1.length - 1; left < s1.length / 2; left++, right--) {
        if (s1[left] != s1[right]) {
            return false;
        }
    }
    return true;
};

image.png

总结:

本篇主要实现了验证回文串的几种方式,通篇下来,多用了双指针方式实现,从结果来看,正则+双指针的方式的执行效率相对要高。