[LeetCode 125] - 验证回文(Valid Palindrome)
问题
给出一个字符串,检查它是不是一个回文。判断过程中只考虑字母数字的字符并且忽略大小写。
例如:
"A man, a plan, a canal: Panama"是一个回文
"race a car"不是一个回文
注意:
在这里我们将空字符串定义为回文
初始思路
判断回文可以使用经典的两头加逼的方法。即使用一个指针指向字符串首部,另一个指针指向字符串尾部。比较被指向的两个字符,如果不等,不是回文,中止比较;如果相等,两个指针各自向中间移动。如此重复直到两指针相交或有字符不等。如判断raceacar:
下标0,r = 下标7,r
下标1,a = 下标6,a
下标2,c = 下标5,c
下标3,e != 下标4,a ==》不为回文。
由于题目的一些限制,在处理时还要注意一些细节:
- 非字母数字字符不参加判断,我们在每次移动指针(下标)时都需要有一个循环跳过这些字符。循环的终止条件为两指针(下标)相交或者指向了一个字母数字字符。
- 非字母数字字符可使用isalnum函数判断。
- 忽略大小写,可在比较字符前统一使用tolower将两个字符皆转成小写。
综上所述,可以得到如下代码:
1 class Solution { 2 public: 3 bool isPalindrome(std::string s) 4 { 5 if(s.empty()) 6 { 7 return true; 8 } 9 10 int right = s.size() - 1; 11 int left = 0; 12 13 while(left < right) 14 { 15 while(!::isalnum(s[left])) 16 { 17 ++left; 18 if(left >= right) 19 { 20 break; 21 } 22 } 23 24 while(!::isalnum(s[right])) 25 { 26 --right; 27 if(right <= left) 28 { 29 break; 30 } 31 } 32 33 if(left >= right) 34 { 35 break; 36 } 37 38 s[left] = ::tolower(s[left]); 39 s[right] = ::tolower(s[right]); 40 if(s[left] != s[right]) 41 { 42 return false; 43 } 44 45 ++left; 46 --right; 47 } 48 49 return true; 50 51 } 52 };
提交后顺利通过Small和Large测试。