// 演算法 / Algorithm:
// 掃一遍字串，記錄每個字母「最後一次小寫」和「第一次大寫」的索引。
// One pass: record each letter's last-lowercase index and first-uppercase index.
// 若兩者都存在且 lastLower < firstUpper，該字母即為 special。
// A letter is special if both exist and lastLower < firstUpper.

int numberOfSpecialChars(char* word) {
    // lastLower[k] = 字母 k 最後一次以小寫出現的索引；-1 表示尚未出現
    // lastLower[k] = index of the last lowercase occurrence of letter k; -1 = not seen
    int lastLower[26];
    // firstUpper[k] = 字母 k 第一次以大寫出現的索引；-1 表示尚未出現
    // firstUpper[k] = index of the first uppercase occurrence of letter k; -1 = not seen
    int firstUpper[26];

    // 初始化兩個陣列為 -1（哨兵值，代表「還沒看到」）
    // Initialize both arrays to -1 (sentinel meaning "not yet seen")
    for (int k = 0; k < 26; k++) {
        lastLower[k] = -1;   // 尚無小寫 / no lowercase yet
        firstUpper[k] = -1;  // 尚無大寫 / no uppercase yet
    }

    // 逐字元掃描；word[i] != '\0' 是 C 字串結尾（空字元）的判斷
    // Scan char by char; '\0' (null terminator) marks the end of a C string
    for (int i = 0; word[i] != '\0'; i++) {
        char c = word[i];  // 取出目前字元 / current character
        if (c >= 'a' && c <= 'z') {
            // 小寫：c - 'a' 把字母映射到 0..25 當作索引；每次覆蓋以保留「最後一次」
            // Lowercase: c - 'a' maps the letter to 0..25; overwrite to keep the LAST index
            lastLower[c - 'a'] = i;
        } else {
            // 大寫：只在第一次（仍為 -1）寫入，以保留「第一次」出現的位置
            // Uppercase: only write when still -1, so it keeps the FIRST occurrence
            if (firstUpper[c - 'A'] == -1) {
                firstUpper[c - 'A'] = i;
            }
        }
    }

    int count = 0;  // 特殊字母計數 / number of special letters
    for (int k = 0; k < 26; k++) {
        // 條件：小寫和大寫都出現過，且最後一個小寫在第一個大寫之前
        // Condition: both cases appeared, and last lowercase is before first uppercase
        if (lastLower[k] != -1 && firstUpper[k] != -1 && lastLower[k] < firstUpper[k]) {
            count++;  // 符合，計入 / matches, count it
        }
    }
    return count;  // 回傳答案 / return the result
}
