题目描述

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

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

示例 1:

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

示例 2:

输入: "race a car"
输出: false
解释:"raceacar" 不是回文串
力扣原题目地址:https://leetcode.cn/problems/...

解决方案

方案一 判断第i项和第j项是否相等(i+j==s.length-1)

下方代码中,我就不区分ij了,直接是i(filterS.length - 1) - i

var isPalindrome = function (s) {
    let flag = true
    // 先加工数据,替换去掉空格特殊符号,以及转成小写英文统一对比
    let filterS = s.replace(/[^A-Za-z0-9]/g, '').toLocaleLowerCase()
    for (let i = 0; i < filterS.length; i++) {
        // 如果有其中一项不符合规则,就直接结束循环,返回结果即可
        if (filterS[i] != filterS[filterS.length - 1 - i]) {
            flag = false
            return flag
        }
    }
    // 最后再返回一下,因为有可能就是回文数,要返回true
    return flag
};

注意,代码中的循环,其实不用循环所有项,只需要循环一半就行了,所以上述代码也可以换一下写法:
for (let i = 0; i < Math.trunc(filterS.length / 2); i++) {......}

注意冷门api之Math.trunc()是取整的意思

  • Math.trunc(2.5) // 2
  • Math.trunc(3) // 3
使用Math.trunc()只循环一半虽然消耗内存少了一些,但是所花费的时间会多一些了,因为Math公式也会花费时间的

方案二 字符串转数组反转对比

var isPalindrome = function (s) {
    // 先加工数据,去掉空格特殊符号,以及转成小写英文统一对比
    let filterS = s.replace(/[^A-Za-z0-9]/g, '').toLocaleLowerCase()
    let filterSArr = filterS.split('') // 转成正常顺序数组
    let filterSArrReverse = filterS.split('').reverse() // 转成倒叙顺序数组
    if (JSON.stringify(filterSArr) == JSON.stringify(filterSArrReverse)) { // 比较是否相等
        return true
    } else {
        return false
    }
};

这方法虽然也能实现,但是性能却是没有方案一好,因为数组的方法反转、以及JSON序列化本身也是要耗费时间的

总结

正常情况下,我们使用空间换时间,多耗费一点点内存,但是时间提速一些,还是划算的。所以方案一是首选

另附正则,只能输入中英文数字 str = str.replace(/[^\u4E00-\u9FA5A-Za-z0-9]/g, '')

水冗水孚
1.1k 声望588 粉丝

每一个不曾起舞的日子,都是对生命的辜负