题目描述
给定一个字符串,判断它是否是回文串。仅考虑大小写字母和数字,忽略其他字符。
注意:规定空字符串也是回文串。在这道题目中,小写字母可以和大写字母匹配,例如 'a'
和 'A'
算相等。
样例1
输入:"A man, a plan, a canal: Panama"
输出:true
样例2
输入:"race a car"
输出:false
算法
(线性扫描) $O(n)$
用两个指针分别从前后开始,往中间扫描。
每次迭代两个指针分别向中间靠近一步,靠近的过程中忽略除了字母和数字的其他字符。
然后判断两个指针所指的字符是否相等,如果不相等,说明不是回文串。
当两个指针相遇时,说明原字符串是回文串。
时间复杂度分析:每个字符仅会被扫描一次,所以时间复杂度是 $O(n)$。
C++ 代码
class Solution {
public:
bool check(char c)
{
return c >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
}
bool isPalindrome(string s) {
int i = 0, j = (int)s.size() - 1;
while (i < j)
{
while (i < j && !check(s[i])) i ++ ;
while (i < j && !check(s[j])) j -- ;
if (s[i] != s[j] && s[i] != (s[j]^32)) return false;
i ++, j --;
}
return true;
}
};
可是为什么是亦或呢?
和大小写字母的Ascii码的二进制表示有关。在相同字母的大小写的二进制表示里,只有第5位不同,异或32可以起到只改变第5位的效果,从而实现大小写的转化。
666
直接写+32,也可以吧,这两个有什么不一样的吗
没啥不一样。不过这样有时候要加32,有时候要减32,要区分一下。
好的,谢谢y总,yyds
class Solution
{
public:
bool validPalindrome(string s)
{
int n = s.size();
int l = 0;
int r = n - 1;
while (l < r)
{
if (s[l] != s[r])
return check(s, l + 1, r) || check(s, l, r - 1);
l ++;
r –;
}
return true;
}
};
作者:Hanxin_Hanxin
链接:https://leetcode-cn.com/problems/RQku0D/solution/cpython3java-shuang-zhi-zhen-by-hanxin_h-0ucb/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
奥利给!
加油hh
为什么这里是亦或32 啊
在ascii码里,大小写字母之间的差是32,比如 ‘a’ - ‘A’ = 32。
谢谢 y 总的解释~~~