问题分析
回文串的定义是正着读和反着读都一样的字符串。对于给定的字符串 s
,我们需要移除所有非字母数字字符,将所有大写字符转换为小写字符,然后判断处理后的字符串是否是回文串。
示例解释
让我们通过示例来理解:
-
输入:
"A man, a plan, a canal: Panama"
- 移除非字母数字字符后:
"amanaplanacanalpanama"
- 正着读和反着读都是相同的,因此是回文串。
- 移除非字母数字字符后:
-
输入:
"race a car"
- 移除非字母数字字符后:
"raceacar"
- 正着读和反着读不同,因此不是回文串。
- 移除非字母数字字符后:
-
输入:
" "
- 移除非字母数字字符后:
""
- 空字符串正着反着读都一样,因此是回文串。
- 移除非字母数字字符后:
C++ 实现
以下是实现该功能的代码及详细解释:
#include <string>
#include <cctype> // 包含用于字符处理的头文件
class Solution {
public:
bool isPalindrome(string s) {
// 定义左右两个指针
int left = 0, right = s.length() - 1;
// 开始遍历字符串
while (left < right) {
// 跳过非字母数字字符,同时将大写字母转换为小写字母
while (left < right && !isalnum(s[left])) {
left++;
}
while (left < right && !isalnum(s[right])) {
right--;
}
// 比较字符是否相同,忽略大小写
if (tolower(s[left]) != tolower(s[right])) {
return false;
}
// 移动指针继续比较下一对字符
left++;
right--;
}
// 如果所有的字符比较都相同,则是回文串
return true;
}
};
代码详解
-
双指针法:
- 使用
left
指针从字符串的开头向后移动,right
指针从末尾向前移动,比较对应位置的字符。
- 使用
-
跳过非字母数字字符:
- 使用
isalnum
函数判断字符是否是字母或数字。 - 如果不是字母数字字符,则指针向前或向后移动,直到找到一个字母或数字字符。
- 使用
-
比较字符:
- 比较
left
和right
指针对应位置的字符,忽略大小写。
- 比较
-
返回结果:
- 如果所有字符比较都相同,则返回
true
,否则返回false
。
- 如果所有字符比较都相同,则返回
复杂度分析
- **时间复杂度:**O(n),其中 n 是字符串的长度。我们只需遍历一次字符串。
- **空间复杂度:**O(1),只使用了常数额外空间。
结论
这个函数利用双指针技术和字符处理函数,高效地判断给定字符串是否是回文串。通过理解和实现这个算法,你可以轻松解决类似的回文串判断问题。