这是我参与2022首次更文挑战的第37天,活动详情查看:2022首次更文挑战
题目描述
提供一个字符串,里面有英文字母,数字,还有其它字符。
现在你需要只考虑字符串的英文字母和数字,英文字母不区分大小写,判断是否为回文字符串。
回文字符串: 正着念和反着念,都是一样的字符串。
补充:如果字符串是空字符串等其它字符,也认为是回文字符串,返回true即可。
例子如下:
字符串:1a, b a1
取英文字母和数字:1aba1
是回文字符串,返回true
字符串:1a, b a
取英文字母和数字:1aba
不是回文字符串,返回false
字符串:`. ,`
属于其它字符,返回true
思路分析
首先既然字符串里面有英文字母,数字,还有其它字符,然后我们只需要英文字母和数字,我们可以使用正则表达式去匹配,匹配到就把它添加到字符串中。
然后现在得到的字符串是包含大小写字母的,我们统一把它转成小写字母。不然无法判断它是不是回文字符串。
然后我们对字符串进行遍历。
首尾开始判断,如果发现有不相等的则直接返回false。
相等的话则继续遍历。
如果遍历到中间的时候,也就是parseInt(len / 2)的时候
如果还是相等,则返回true即可。
为什么是parseInt(len / 2),因为字符串的长度有奇偶之分
如果是奇数,则len/2是小数,我们只需要遍历它的前一位即可,所以用parseInt取整就行。只要它前面都是回文字符串,那它就是回文字符串。
如果是偶数,则parseInt(len / 2)等于len / 2,遍历到这里的时候已经满足是回文字符串了。
其它情况,比如空字符串,特殊字符这些,返回true即可。
代码如下:
/**
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function (s) {
let str = ''
s.replace(/[0-9A-Za-z]/g, ($0) => {
str += $0
})
str = str.toLocaleLowerCase()
const len = str.length
for (let i = 0; i < len; i++) {
if (i === parseInt(len / 2)) return true
if (str[i] !== str[len - i - 1]) return false
}
return true
};
还有另外一种解法,思路类似。
使用while循环,左索引从首部开始,右索引从尾部开始,向中间靠拢。
如果对应的值相等则继续判断。
只要不相等就返回false。
等到左索引大于右索引,则证明已经该字符串是回文字符串。返回true即可。
/**
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function (s) {
s = s.replace(/[\W_]/g, '')
s = s.toLocaleLowerCase()
let left = 0
let right = s.length - 1
while (left < right) {
if (s[left] !== s[right]) return false
left++
right--
}
return true
};