Problem

You are given a string word. A letter is called special if it appears both in lowercase and uppercase in word.

Return the number of __special letters in __word.

Examples

Example 1

1
2
3
4
5
6
7
8

Input: word = "aaAbcBC"

Output: 3

Explanation:

The special characters in `word` are `'a'`, `'b'`, and `'c'`.

Example 2

1
2
3
4
5
6
7
8

Input: word = "abc"

Output: 0

Explanation:

No character in `word` appears in uppercase.

Example 3

1
2
3
4
5
6
7
8

Input: word = "abBCab"

Output: 1

Explanation:

The only special character in `word` is `'b'`.

Constraints

  • 1 <= word.length <= 50
  • word consists of only lowercase and uppercase English letters.

Solution

Method 1 – Set Based Counting

Intuition

A letter is special if both its lowercase and uppercase forms appear in the string. We can use sets to track which lowercase and uppercase letters are present, then count how many letters appear in both forms.

Approach

  1. Initialize two sets: one for lowercase, one for uppercase letters.
  2. Iterate through the string:
    • If the character is lowercase, add to the lowercase set.
    • If uppercase, add to the uppercase set.
  3. For each letter from ‘a’ to ‘z’, check if both its lowercase and uppercase forms are present in the respective sets.
  4. Count and return the number of such letters.

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution {
public:
    int numberOfSpecialChars(string word) {
        unordered_set<char> lower, upper;
        for (char c : word) {
            if (islower(c)) lower.insert(c);
            else if (isupper(c)) upper.insert(c);
        }
        int ans = 0;
        for (char c = 'a'; c <= 'z'; ++c) {
            if (lower.count(c) && upper.count(c - 'a' + 'A')) ++ans;
        }
        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
func numberOfSpecialChars(word string) int {
    lower := make(map[rune]bool)
    upper := make(map[rune]bool)
    for _, c := range word {
        if c >= 'a' && c <= 'z' {
            lower[c] = true
        } else if c >= 'A' && c <= 'Z' {
            upper[c] = true
        }
    }
    ans := 0
    for c := 'a'; c <= 'z'; c++ {
        if lower[c] && upper[c-'a'+'A'] {
            ans++
        }
    }
    return ans
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution {
    public int numberOfSpecialChars(String word) {
        Set<Character> lower = new HashSet<>();
        Set<Character> upper = new HashSet<>();
        for (char c : word.toCharArray()) {
            if (Character.isLowerCase(c)) lower.add(c);
            else if (Character.isUpperCase(c)) upper.add(c);
        }
        int ans = 0;
        for (char c = 'a'; c <= 'z'; ++c) {
            if (lower.contains(c) && upper.contains((char)(c - 'a' + 'A'))) ans++;
        }
        return ans;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution {
    fun numberOfSpecialChars(word: String): Int {
        val lower = mutableSetOf<Char>()
        val upper = mutableSetOf<Char>()
        for (c in word) {
            if (c.isLowerCase()) lower.add(c)
            else if (c.isUpperCase()) upper.add(c)
        }
        var ans = 0
        for (c in 'a'..'z') {
            if (lower.contains(c) && upper.contains(c.uppercaseChar())) ans++
        }
        return ans
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution:
    def numberOfSpecialChars(self, word: str) -> int:
        lower: set[str] = set()
        upper: set[str] = set()
        for c in word:
            if c.islower():
                lower.add(c)
            elif c.isupper():
                upper.add(c)
        ans = 0
        for i in range(26):
            ch = chr(ord('a') + i)
            if ch in lower and ch.upper() in upper:
                ans += 1
        return ans
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
impl Solution {
    pub fn number_of_special_chars(word: String) -> i32 {
        let mut lower = std::collections::HashSet::new();
        let mut upper = std::collections::HashSet::new();
        for c in word.chars() {
            if c.is_ascii_lowercase() {
                lower.insert(c);
            } else if c.is_ascii_uppercase() {
                upper.insert(c);
            }
        }
        let mut ans = 0;
        for c in b'a'..=b'z' {
            if lower.contains(&(c as char)) && upper.contains(&((c as char).to_ascii_uppercase())) {
                ans += 1;
            }
        }
        ans
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class Solution {
    numberOfSpecialChars(word: string): number {
        const lower = new Set<string>()
        const upper = new Set<string>()
        for (const c of word) {
            if (c >= 'a' && c <= 'z') lower.add(c)
            else if (c >= 'A' && c <= 'Z') upper.add(c)
        }
        let ans = 0
        for (let i = 0; i < 26; ++i) {
            const ch = String.fromCharCode(97 + i)
            if (lower.has(ch) && upper.has(ch.toUpperCase())) ans++
        }
        return ans
    }
}

Complexity

  • ⏰ Time complexity: O(n) where n is the length of the string, as we scan the string and check 26 letters.
  • 🧺 Space complexity: O(1) since the sets store at most 26 lowercase and 26 uppercase letters.