LC125. 验证回文串(第22题)

145 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

菜鸟就要从第22题继续

一、题目描述:

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

说明:本题中,我们将空字符串定义为有效的回文串。

示例 1: 输入: "A man, a plan, a canal: Panama" 输出: true 解释:"amanaplanacanalpanama" 是回文串

示例 2: 输入: "race a car" 输出: false 解释:"raceacar" 不是回文串  

提示:

1 <= s.length <= 2 * 105 字符串 s 由 ASCII 字符组成

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/va… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

首先,这道题的重点其实不是回文串,而是只考虑字母和数字字符,可以忽略字母的大小写。

  • toLowerCase()toUpperCase() 这两个方法分别用于将字符串 str 中的所有大写字母转换为小写字母以及将所有小写字母转换为大写字母。

  • match(/[a-z0-9]+/g);match方法+正则可以替换 match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配,注意结果为数组。 g :执行全局匹配(查找所有匹配而非在找到第一个匹配后停止) [0-9]:查找任何从 0 至 9 的数字; [a-z]: 查找任何从小写 a 到小写 z 的字符。

  • 通过函数比较ASCII码值的大小判断是否属于数字字母范围

function isValid(str){
    return str >= 'a' && str <= 'z' || str >= '0' && str <= '9';
}

回文处理就是三种方法reverse、双指针、栈,代码如下。

三、AC 代码:

1、reverse

/**
 * @param {string} s
 * @return {boolean}
 */
var isPalindrome = function(s) {
    let news = s.toLowerCase().match(/[0-9a-z]+/g)
    if(!news) return true 
    let str = news.join("");//注意拆成的数据要拼成字符串
    let comp = str.split("").reverse().join("");// 将字符串翻转
    return comp === str;
};

2、双指针

/**
 * @param {string} s
 * @return {boolean}
 */
var isPalindrome = function(s) {
    let str = s.toLowerCase();
    let i = 0;
    let j = str.length - 1;
    while(i < j){
        // i/j不符合下面的isValid就推动左/右指针 并结束本轮迭代
        if(!isValid(str[i])){
            i++;
            continue;
        }
        if(!isValid(str[j])){
            j--;
            continue;
        }
        if(str[i] !== str[j]){
            return false;
        }
        i++;
        j--;
    }
    return true;
};
var isValid = function(str){
    return (str >= 'a' && str <= 'z') || (str >= '0' && str <= '9');
}

3、栈

var isPalindrome = function(s) {
    let valid = s.toLowerCase().match(/[a-z0-9]+/g);
    if(!valid){
        return true;
    }
    let str = valid.join("");// 正则匹配过后获得的字符串
    let stack = [];
    
    let mid = str.length >> 1;// 设置中间的位置,入栈至str[mid - 1]再遍历后续内容 并与栈中内容一一比对
    for(let i = 0; i < mid; i++){
        stack.push(str[i]);
    }
    // 入栈完毕,接下来进行比对
    // 额外注意:如果字符串长度为奇数,应该跳过中间的字符进行比对
    if(str.length % 2){
        mid++;
    }
    for(let i = mid; i < str.length; i++){
        let comp = stack.pop();// 将元素一一出栈
        if(comp !== str[i]){
            return false;
        }
    }
    return true;
};