"\"Stop!\" nine myriad murmur. \"Put up rum, rum, dairymen, in pots.\"": 一開始只寫了
else {s.erase(i,1); i -=2; }
可是如果 i == 0 時就有 char 被移除掉,那就會發生 i = -2 的情況,就會出問題,所以要改成:
else {s.erase(i,1);if(i!=0) i -=2;else i=0; }
"......a.....": 這個也是錯在 i 的變化,應該要長得像下面這樣
else {s.erase(i,1);if(i!=0) i -=2;else i=-1; // reset 下次 i 從 0 開始 }
最後程式碼如下:
classSolution {public:boolisPalindrome(string s) {if(s.empty()) returntrue; // to lower case // https://stackoverflow.com/questions/313970/how-to-convert-stdstring-to-lower-casetransform(s.begin(),s.end(),s.begin(), ::tolower); // remove other character // http://www.cplusplus.com/reference/cctype/isalnum/for(int i=0; i<s.length(); i++) { if(isalnum(s[i])) continue;else {s.erase(i,1);if(i!=0) i -=2;else i=-1; } } // two pointer compareint begin=0, end=s.length()-1;while(begin<end) {if(s[begin] !=s[end])returnfalse; begin++; end--; }returntrue; }};
以上這種寫法實在太醜了,而且效率超級低,時間複雜度 O(3n): Runtime: 484 ms, faster than 5.17% of C++ online submissions for Valid Palindrome. Memory Usage: 9.3 MB, less than 60.81% of C++ online submissions for Valid Palindrome.
解法二 - 直接 Two Pointer
其實不需要全部先轉 lower case 跟移除非 alphanumeric 的 char:
classSolution {public:boolisPalindrome(string s) { // Use 2 pointers to traverse from both sideint l =0, r =s.length()-1; // Check if s[l] == s[r] while( l < r ) {while( l <s.length() &&!isalnum(s[l]) ) {++l; }while( r >=0&&!isalnum(s[r]) ) {--r; }if( r <0or l >=s.length()) {break; }if( tolower(s[l]) !=tolower(s[r]) ) {returnfalse; }++l;--r; }returntrue; }};
上面這個做法雖然會過,但程式碼有點冗長,比較好的實作方法是:
classSolution {public:boolisPalindrome(string s) {for(int i=0, j=s.length()-1; i<j; i++, j--) {while(isalnum(s[i])==false&& i<j) i++; // Increment left ptr if not alphanumericwhile(isalnum(s[j])==false&& i<j) j--; // Decrement right ptr if not alphanumericif(tolower(s[i]) !=tolower(s[j]))returnfalse; }returntrue; }};
而且效率高多了:
Runtime: 4 ms, faster than 99.62% of C++ online submissions for Valid Palindrome. Memory Usage: 9.3 MB, less than 68.07% of C++ online submissions for Valid Palindrome.