题目:验证回文串
描述:
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
示例 1:
输入: s = “A man, a plan, a canal: Panama”
输出:true
解释:“amanaplanacanalpanama” 是回文串。
leetcode链接
方法一:模拟
把删除修改后的字符串用另一个字符串进行存储,然后再判断是不是回文串
时间复杂度:o(n)
空间复杂度:o(n) n为字符串的长度,我们用到了新的字符串存储修改后的字符串
bool isPalindrome(string s) {
string newStr;
for(int i=0;i<s.size();i++){
if(s[i]>='a'&&s[i]<='z'||s[i]>='0'&&s[i]<='9'){
newStr+=s[i];
}else if(s[i]>='A'&&s[i]<='Z'){
newStr+=s[i]-'A'+'a';
}
}
cout<<newStr;
int first = 0,end = newStr.size()-1;
while(first<end){
if(newStr[first++]!=newStr[end--]){
return false;
}
}
return true;
}
方法二:
考虑对方法一进行优化,我们不用新的字符串存储改变后的字符串,而是直接在原字符串上进行判断,利用双指针发,定义left和right两个指针分别指向头尾,这两个指针会遇到这样的情况
- 两个指针所指向的元素都满足条件(即为小写字母或者数字)
- 两个指针有一个或多个为大写字母,把大写字母改为小写字母再进行比较
- 有一个或多个指针为不是大写字母的不满足条件的元素,不满足条件的指针移动,满足条件的指针不动,直达遇到满足条件的元素为止,再进行对比
时间复杂度:o(n) 空间复杂度:o(1) 没有申请额外的空间
补充:c++中判断一个字符为字母或者为数字的函数为isalnum()
是则返回true,否则返回false
c++中实现大小写转换的函数为tolower()/toupper()
前者为大写转小写,后者为小写转大写
bool isPalindrome(string s) {
int left = 0,right = s.size()-1;
while(left<right){
//遇到非法字符指针移动,知道找到合法字符为止
while(left<right&&!isalnum(s[left])){
left++;
}
while(left<right&&!isalnum(s[right])){
right--;
}
//如果遇到大写字母转小写字母,再进行判断
if(left<right&&tolower(s[left])!=tolower(s[right])){
return false;
}
//比较完成之后记得要移动指针
left++;
right--;
}
return true;
}