LeetCode 3120: Count the Number of Special Characters I (Lower/Upper Presence Check)
LeetCode 3120StringCountingToday we solve LeetCode 3120 - Count the Number of Special Characters I.
Source: https://leetcode.com/problems/count-the-number-of-special-characters-i/
English
Problem Summary
Given a string word, a letter is called special if both lowercase and uppercase forms appear in the string. Return how many letters are special.
Key Insight
There are only 26 English letters. We can scan once, mark whether each lowercase letter appears and whether each uppercase letter appears, then count indices where both are true.
Algorithm
- Create two boolean arrays of size 26: lower and upper.
- For each character in word, mark the corresponding array.
- Iterate from 0..25, count positions where both arrays are true.
Complexity Analysis
Let n be the string length.
Time: O(n + 26) = O(n).
Space: O(26 + 26) = O(1).
Common Pitfalls
- Forgetting uppercase/lowercase index conversion.
- Counting duplicated letters multiple times instead of once per alphabet letter.
- Using expensive per-letter scans repeatedly.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public int numberOfSpecialChars(String word) {
boolean[] lower = new boolean[26];
boolean[] upper = new boolean[26];
for (char c : word.toCharArray()) {
if (c >= 'a' && c <= 'z') {
lower[c - 'a'] = true;
} else if (c >= 'A' && c <= 'Z') {
upper[c - 'A'] = true;
}
}
int ans = 0;
for (int i = 0; i < 26; i++) {
if (lower[i] && upper[i]) {
ans++;
}
}
return ans;
}
}func numberOfSpecialChars(word string) int {
lower := make([]bool, 26)
upper := make([]bool, 26)
for _, c := range word {
if c >= 'a' && c <= 'z' {
lower[c-'a'] = true
} else if c >= 'A' && c <= 'Z' {
upper[c-'A'] = true
}
}
ans := 0
for i := 0; i < 26; i++ {
if lower[i] && upper[i] {
ans++
}
}
return ans
}class Solution {
public:
int numberOfSpecialChars(string word) {
vector<bool> lower(26, false), upper(26, false);
for (char c : word) {
if (c >= 'a' && c <= 'z') {
lower[c - 'a'] = true;
} else if (c >= 'A' && c <= 'Z') {
upper[c - 'A'] = true;
}
}
int ans = 0;
for (int i = 0; i < 26; i++) {
if (lower[i] && upper[i]) {
ans++;
}
}
return ans;
}
};class Solution:
def numberOfSpecialChars(self, word: str) -> int:
lower = [False] * 26
upper = [False] * 26
for c in word:
if 'a' <= c <= 'z':
lower[ord(c) - ord('a')] = True
elif 'A' <= c <= 'Z':
upper[ord(c) - ord('A')] = True
ans = 0
for i in range(26):
if lower[i] and upper[i]:
ans += 1
return ans/**
* @param {string} word
* @return {number}
*/
var numberOfSpecialChars = function(word) {
const lower = new Array(26).fill(false);
const upper = new Array(26).fill(false);
for (const ch of word) {
if (ch >= 'a' && ch <= 'z') {
lower[ch.charCodeAt(0) - 97] = true;
} else if (ch >= 'A' && ch <= 'Z') {
upper[ch.charCodeAt(0) - 65] = true;
}
}
let ans = 0;
for (let i = 0; i < 26; i++) {
if (lower[i] && upper[i]) {
ans++;
}
}
return ans;
};中文
题目概述
给定字符串 word,如果某个字母的小写和大写都在字符串中出现,则该字母是 special。返回 special 字母的数量。
核心思路
英文字母只有 26 个。一次遍历分别记录每个字母的小写是否出现、大写是否出现,最后统计同时出现的下标数量即可。
算法步骤
- 准备两个长度为 26 的布尔数组:lower 与 upper。
- 遍历 word,按字符类型更新对应数组。
- 再遍历 0..25,若 lower[i] 和 upper[i] 同时为真则计数。
复杂度分析
设字符串长度为 n。
时间复杂度:O(n + 26),即 O(n)。
空间复杂度:O(1)。
常见陷阱
- 大小写转换时下标偏移写错。
- 把同一个字母重复计数多次,而不是按字母种类计数。
- 对每个字母重复扫描字符串导致额外开销。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public int numberOfSpecialChars(String word) {
boolean[] lower = new boolean[26];
boolean[] upper = new boolean[26];
for (char c : word.toCharArray()) {
if (c >= 'a' && c <= 'z') {
lower[c - 'a'] = true;
} else if (c >= 'A' && c <= 'Z') {
upper[c - 'A'] = true;
}
}
int ans = 0;
for (int i = 0; i < 26; i++) {
if (lower[i] && upper[i]) {
ans++;
}
}
return ans;
}
}func numberOfSpecialChars(word string) int {
lower := make([]bool, 26)
upper := make([]bool, 26)
for _, c := range word {
if c >= 'a' && c <= 'z' {
lower[c-'a'] = true
} else if c >= 'A' && c <= 'Z' {
upper[c-'A'] = true
}
}
ans := 0
for i := 0; i < 26; i++ {
if lower[i] && upper[i] {
ans++
}
}
return ans
}class Solution {
public:
int numberOfSpecialChars(string word) {
vector<bool> lower(26, false), upper(26, false);
for (char c : word) {
if (c >= 'a' && c <= 'z') {
lower[c - 'a'] = true;
} else if (c >= 'A' && c <= 'Z') {
upper[c - 'A'] = true;
}
}
int ans = 0;
for (int i = 0; i < 26; i++) {
if (lower[i] && upper[i]) {
ans++;
}
}
return ans;
}
};class Solution:
def numberOfSpecialChars(self, word: str) -> int:
lower = [False] * 26
upper = [False] * 26
for c in word:
if 'a' <= c <= 'z':
lower[ord(c) - ord('a')] = True
elif 'A' <= c <= 'Z':
upper[ord(c) - ord('A')] = True
ans = 0
for i in range(26):
if lower[i] and upper[i]:
ans += 1
return ans/**
* @param {string} word
* @return {number}
*/
var numberOfSpecialChars = function(word) {
const lower = new Array(26).fill(false);
const upper = new Array(26).fill(false);
for (const ch of word) {
if (ch >= 'a' && ch <= 'z') {
lower[ch.charCodeAt(0) - 97] = true;
} else if (ch >= 'A' && ch <= 'Z') {
upper[ch.charCodeAt(0) - 65] = true;
}
}
let ans = 0;
for (let i = 0; i < 26; i++) {
if (lower[i] && upper[i]) {
ans++;
}
}
return ans;
};
Comments