如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 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 是一个空字符串 "" 。 由于空字符串正着反着读都一样,所以是回文串。
提示:
1 <= s.length <= 2 * 105
s
仅由可打印的 ASCII 字符组成
1.isalnum()函数
函数名:isalnum
函数原型:int isalnum(int c);
所需头文件:<cctype>
功能:测试 c 是否字母或数字。
返回值:如果 c 在 A~Z、a~z 或0~9的范围内,则返回一个非0值;否则返回0。
2.tolower() 语法
用法:
tolower(int ch);
参数:
tolower()
函数接受以下参数:
- ch- 一个角色,投射到
int
输入或EOF
返回:
tolower()
函数返回:
- 对于字母- 小写版本的 ASCII 码
ch
- 对于非字母- 的 ASCII 码
ch
3.string类对象末尾添加字符:
string s; char ch='a'; s=s+ch;
4.思路:
首先遍历s1初始字符串,使用isalnum()函数判断字符是否满足条件,满足的添加到另一字符串s2中,再s2中利用双指针遍历,头指针从第一个元素位置向右遍历,尾指针从最后一个位置向左,遍历次数为(s2.size())/2
解法一:
class Solution { public://大写转小写:A+32 bool isPalindrome(string s) { int n=s.size(); string s2;//s2为处理后的字符串 int j; for (char ch: s) { if (isalnum(ch)) { s2 += tolower(ch); } } int flag=0; for(int i=0;i<s2.size()/2;i++) { j=s2.size()-i-1; if(s2[i]!=s2[j]) {flag=1;} } if(flag==0){return true;} else { return false; } } };
解法二:(优化了内存):直接在原字符串上比较
思路:双指针l(从头往尾),r(尾往头)。
比较结束条件:l与r相遇,若不相遇,且对应字符串不相等,则直接return FALSE;否则l++,r--;若一直到结束也没有return FALSE;则returnTRUE;
class Solution { public: bool isPalindrome(string s) { int l=0;int r=s.size()-1; //防止内存超限 while(l<r) { while(!isalnum(s[l])&&l<s.size()-1) { l++; } while(!isalnum(s[r])&&r>0) { r--; } if(l>=r){break;} if(tolower(s[l])==tolower(s[r])){r--;l++;} else { return false;break; } } return true;} };