[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 馬拉車演算法。
參考資料: