LeetCode125、 验证回文串

83 阅读1分钟

LeetCode 系列记录我学习算法的过程。

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情

题目

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

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

示例:

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


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

提示:

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

思路

这个题目也是求一个字符串是不是回文字符串,但是和之前哪个题目有点区别

要求只考虑数字和字母,且不考虑字母大小写,其他字符全部都不需要考虑,所以大体思路和之前差不多

不过要先将字符串全部转成小写,然后根据 ASCII 码来进行判断是否在考虑范围:

  • 首先定义变量获取字符串转小写后的值,然后获取字符串长度
  • 初始化两个指针,分别指向开头和结尾
  • 开始遍历字符串,结束条件为首尾指针相遇后
  • 获取首尾指针指向的字符的 ASCII 码,然后判断是否属于数字或字母
  • 如果不属于则移动对应指针并跳过本次循环
  • 如果都属于,则判断是否相等,相等则继续移动两个指针,反之则返回false
  • 最后遍历结束则返回true

代码实现

/**
 * @param {string} s
 * @return {boolean}
 */
var isPalindrome = function(s) {
    // 字符串转小写后的值
    const lowStr = s.toLowerCase()
    // 首尾指针和字符串长度
    let x = 0, y = s.length - 1
    // 开始遍历
    while(x < y) {
        // 获取首尾指针指向的字符 ASCII码
        const xCode = lowStr[x].charCodeAt()
        const yCode = lowStr[y].charCodeAt()
        // 分别判断是否属于 数字 或 字母
        if(xCode > 122 || (xCode < 97 && xCode > 57) || xCode < 48) {
            // 不属于则移动指针并跳过本次循环
            x++
            continue
        }
        if(yCode > 122 || (yCode < 97 && yCode > 57) || yCode < 48) {
            y--
            continue
        }
        // 都属于则进行比较,相同则移动两个指针
        if(lowStr[x] === lowStr[y]) {
            x++
            y--
        } else {
        // 反之返回 false
            return false
        }
    }
    // 遍历结束返回 true
    return true
};

image.png

优化

代码简洁的一种写法,先用正则匹配出字母和数字,然后转小写,最后双指针遍历判断即可

var isPalindrome = function(s) {
    const str = s.toLowerCase().replace(/[^a-zA-Z0-9]/g,'')
    let x = 0, y = str.length - 1
    while(x < y) {
        if(str[x++] !== str[y--]){
            return false
        }
    }
    return true
};

image.png