题目描述
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例
示例1:
输入: "A man, a plan, a canal: Panama"
输出: true
示例2:
输入: "race a car"
输出: false
解题思路
判断是否是回文串,就相当于该字符串从中间分开的左右两边是不是相等的,可以理解成该字符串是不是关于中心对称的。既然涉及到了左右两边,那么第一想到的应该就是双指针了。
思路一
- 为了方便,我们不妨先将字符串全部转为大写或者小写的;
- 双指针那就来咯:定义左指针从字符串第一个元素开始移动,右指针从字符串最后一个开始移动, 两个指针相向移动;
- 那么问题来了,因为字符串中含有空格以及标点符号,那么怎么办呢?
- 题目说了只考虑字符串中的数字和不计大小的字母,所以我们可以写一个函数来判断当前指针指的到底是不是字母或者数字就行了,如果是的话,就返回true;否则返回false;
- 那么我们要先判断左右指针指向的值是否满足条件,满足条件再对两指针进行比较,如果不相等就直接返回false;相等则继续比较,直到两指针相遇,跳出循环;
思路二
还有一种简便的方法,就是用正则表达式把字符串中除了字母和数字的其他全部替换掉为空,那么剩下的就是一个只有数字和字母的字符串,那么就不需要另外定义个方法了,再结合双指针来取得最终解。
AC代码
代码1
var isPalindrome = function(s) {
s = s.toLowerCase()
let i = 0, j = s.length - 1
while(i < j) {
if(!isvalid(s[i])) {
i++
continue
}
if(!isvalid(s[j])) {
j--
continue
}
if(s[i] == s[j]) {
i++
j--
} else {
return false
}
}
return true
};
let isvalid = (str) => {
return (str >= 'a' && str <= 'z') || (str >= '0' && str <= '9')
}
代码2
var isPalindrome = function(s) {
// \W 的意思就是查找单词字符
// 单词字符包括:a-z、A-Z、0-9,以及下划线, 包含 _ (下划线) 字符。
// 等价于 '[^A-Za-z0-9_]'
s = s.replace(/\W|_/g,'').toLowerCase()
let i = 0, j = s.length - 1
while(i < j) {
if(s[i] != s[j]) {
return false
}
i++
j--
}
return true
}
总结
就目前我做的很多道题,我发现很多都是用双指针来作答,所以有时候做题的时候看一眼类似的题目就很容易联想到用双指针来解题。所以还是要多刷算法题,多掌握一些算法思想理念,做起题来才能够更加的得心应手啊。路还在走,加油吧!
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情