125. 验证回文串
题目描述
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
输入/输出示例
示例 1:
输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。
示例 2:
输入:s = "race a car"
输出:false
解释:"raceacar" 不是回文串。
示例 3:
输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。
由于空字符串正着反着读都一样,所以是回文串。
常规解法
关键思路 - 字符串遍历
- 用正则表达式筛选出合适的字母/数字,再进行遍历,判断首尾字符是否相同。
JS代码实现
/**
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function (s) {
let str = s.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
let len = str.length;
for (let i = 0; i < len / 2; i++) {
if (str[i] !== str[len - 1 - i]) {
return false;
}
}
return true;
};
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(n)
优化解法2
关键思路 - 排序后直接比较
- 用正则表达式筛选出合适的字母/数字后,直接用reverse方法反转字符串,看前后两个字符串是否相等
JS代码实现
/**
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function (s) {
let str = s.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
return str === str.split('').reverse().join('');
};
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(n)
优化解法1
关键思路 - 排序后直接比较
- 用正则表达式筛选出合适的字母/数字后,直接用reverse方法反转字符串,看前后两个字符串是否相等
JS代码实现
/**
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function (s) {
let str = s.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
return str === str.split('').reverse().join('');
};
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(n)
优化解法2
关键思路 - 双指针比较
- 上述两种解法都是通过筛选,形成一个新的字符串,再进行遍历比较。
- 能不能不通过筛选,直接比较呢?
JS代码实现
/**
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function (s) {
let left = 0;
let right = s.length - 1;
while (left < right) {
// 跳过非字母数字字符
while (left < right && !/^[a-zA-Z0-9]$/.test(s[left])) {
left++;
}
while (left < right && !/^[a-zA-Z0-9]$/.test(s[right])) {
right--;
}
// 比较字符
if (s[left].toLowerCase() !== s[right].toLowerCase()) {
return false;
}
left++;
right--;
}
return true;
};
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)
结语
本文主要介绍了LeetCode第125题验证回文串的解法,你还知道这题的其他解法吗?欢迎在评论区留言分享!