[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 };
isPalindrome

提交后顺利通过Small和Large测试。

 

posted @ 2013-06-07 23:32  Shawnone  阅读(918)  评论(0编辑  收藏  举报