// Algorithm / 演算法：
//   Identical two-pointer approach: skip non-alphanumeric characters from
//   both ends, compare lowercase forms, shrink inward.
//   做法與 C 版相同：雙指針 + 跳過非字母數字 + 小寫比較。
//   Time O(n), Space O(1).

#include <string>      // std::string 字串型別 / std::string type
#include <cctype>      // std::isalnum, std::tolower 字元工具 / char helpers

class Solution {
public:
    bool isPalindrome(std::string s) {
        int left  = 0;                            // 左指針 / left index
        int right = static_cast<int>(s.size()) - 1; // 右指針，s.size() 回傳長度 / right index; size() returns length

        while (left < right) {                    // 還沒交會就繼續 / loop until pointers cross
            // 用 unsigned char 包裝再傳入 isalnum/tolower，避免負值 UB
            // Wrap in unsigned char to avoid UB with negative char values
            unsigned char lc = static_cast<unsigned char>(s[left]);
            unsigned char rc = static_cast<unsigned char>(s[right]);

            if (!std::isalnum(lc)) {              // 左非字母數字就跳過 / skip non-alnum on the left
                ++left;                           // 前置 ++ 與後置 ++ 在這裡效果相同 / prefix ++ here
                continue;                         // 進入下一輪迴圈 / next iteration
            }
            if (!std::isalnum(rc)) {              // 右非字母數字就跳過 / skip non-alnum on the right
                --right;                          // 右指針左移 / move right inward
                continue;
            }

            // 兩邊都是有效字元 → 比較小寫 / both valid → compare lowercase
            if (std::tolower(lc) != std::tolower(rc)) {
                return false;                     // 不相等 → 不是回文 / mismatch → not palindrome
            }

            ++left;                               // 配對成功，往中間收 / matched, shrink window
            --right;
        }

        return true;                              // 所有對稱位置皆相等 / all symmetric pairs matched
    }
};
