1. 程式人生 > >[LeetCode] Valid Palindrome 驗證迴文字串

[LeetCode] Valid Palindrome 驗證迴文字串

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

For example,
"A man, a plan, a canal: Panama" is a palindrome.
"race a car" is not a palindrome.

Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.

For the purpose of this problem, we define empty string as valid palindrome.

驗證迴文字串是比較常見的問題,所謂迴文,就是一個正讀和反讀都一樣的字串,比如“level”或者“noon”等等就是迴文串。但是這裡,加入了空格和非字母數字的字元,增加了些難度,但其實原理還是很簡單:只需要建立兩個指標,left和right, 分別從字元的開頭和結尾處開始遍歷整個字串,如果遇到非字母數字的字元就跳過,繼續往下找,直到找到下一個字母數字或者結束遍歷,如果遇到大寫字母,就將其轉為小寫。等左右指標都找到字母數字時,比較這兩個字元,若相等,則繼續比較下面兩個分別找到的字母數字,若不相等,直接返回false. 

時間複雜度為O(n), 程式碼如下:

解法一:

class Solution {
public:
    bool isPalindrome(string s) {
        int left = 0, right = s.size() - 1 ;
        while (left < right) {
            if (!isAlphaNum(s[left])) ++left;
            else if (!isAlphaNum(s[right])) --right;
            else if ((s[left] + 32
- 'a') %32 != (s[right] + 32 - 'a') % 32) return false; else { ++left; --right; } } return true; } bool isAlphaNum(char &ch) { if (ch >= 'a' && ch <= 'z') return true; if (ch >= 'A' && ch <= 'Z') return true; if (ch >= '0' && ch <= '9') return true; return false; } };

我們也可以用系統自帶的判斷是否是數母字元的判斷函式isalnum,參見程式碼如下;

解法二:

class Solution {
public:
    bool isPalindrome(string s) {
        int left = 0, right = s.size() - 1 ;
        while (left < right) {
            if (!isalnum(s[left])) ++left;
            else if (!isalnum(s[right])) --right;
            else if ((s[left] + 32 - 'a') %32 != (s[right] + 32 - 'a') % 32) return false;
            else {
                ++left; --right;
            }
        }
        return true;
    }
};

對於該問題的擴充套件,還有利用Manacher演算法來求解最長迴文字串問題,參見我的另一篇博文Manacher's Algorithm 馬拉車演算法

參考資料: