Easy

题目描述

给你一个字符串 word。如果一个字母在 word 中既以小写形式出现又以大写形式出现,则称这个字母为特殊字母

返回 word 中特殊字母的数量。

示例 1:

输入:word = "aaAbcBC"
输出:3
解释:word 中的特殊字符是 'a'、'b' 和 'c'。

示例 2:

输入:word = "abc"
输出:0
解释:word 中没有字符以大写形式出现。

示例 3:

输入:word = "abBCab"
输出:1
解释:word 中唯一的特殊字符是 'b'。

提示:

  • 1 <= word.length <= 50
  • word 仅由小写和大写英文字母组成。

解题思路

这道题的核心思路是统计每个字母的大小写出现情况,然后计算有多少字母同时以大小写形式出现。

解法思路

方法一:哈希表统计(推荐)

  1. 使用两个集合分别记录出现的小写字母和大写字母
  2. 遍历字符串,将字符按照大小写分别加入对应集合
  3. 遍历26个字母,检查每个字母是否同时在两个集合中出现
  4. 统计满足条件的字母数量

方法二:位运算优化 使用两个整数的二进制位来表示字母的出现状态,每个字母对应一个位。这种方法空间效率更高,但代码稍复杂。

方法三:暴力枚举 对于每个可能的字母(a-z),直接在字符串中检查其大小写形式是否都存在。

由于字符串长度最大只有50,字母总数固定为26个,所有方法的时间复杂度都是可接受的。推荐使用哈希表方法,代码简洁易懂。

代码实现

class Solution {
public:
    int numberOfSpecialChars(string word) {
        unordered_set<char> lowercase, uppercase;
        
        for (char c : word) {
            if (c >= 'a' && c <= 'z') {
                lowercase.insert(c);
            } else {
                uppercase.insert(c);
            }
        }
        
        int count = 0;
        for (char c = 'a'; c <= 'z'; c++) {
            if (lowercase.count(c) && uppercase.count(c - 'a' + 'A')) {
                count++;
            }
        }
        
        return count;
    }
};
class Solution:
    def numberOfSpecialChars(self, word: str) -> int:
        lowercase = set()
        uppercase = set()
        
        for c in word:
            if c.islower():
                lowercase.add(c)
            else:
                uppercase.add(c)
        
        count = 0
        for c in 'abcdefghijklmnopqrstuvwxyz':
            if c in lowercase and c.upper() in uppercase:
                count += 1
                
        return count
public class Solution {
    public int NumberOfSpecialChars(string word) {
        HashSet<char> lowercase = new HashSet<char>();
        HashSet<char> uppercase = new HashSet<char>();
        
        foreach (char c in word) {
            if (char.IsLower(c)) {
                lowercase.Add(c);
            } else {
                uppercase.Add(c);
            }
        }
        
        int count = 0;
        for (char c = 'a'; c <= 'z'; c++) {
            if (lowercase.Contains(c) && uppercase.Contains(char.ToUpper(c))) {
                count++;
            }
        }
        
        return count;
    }
}
var numberOfSpecialChars = function(word) {
    const lowercase = new Set();
    const uppercase = new Set();
    
    for (const c of word) {
        if (c >= 'a' && c <= 'z') {
            lowercase.add(c);
        } else {
            uppercase.add(c);
        }
    }
    
    let count = 0;
    for (let i = 0; i < 26; i++) {
        const lowerChar = String.fromCharCode('a'.charCodeAt(0) + i);
        const upperChar = String.fromCharCode('A'.charCodeAt(0) + i);
        if (lowercase.has(lowerChar) && uppercase.has(upperChar)) {
            count++;
        }
    }
    
    return count;
};

复杂度分析

解法时间复杂度空间复杂度
哈希表统计O(n + 26) = O(n)O(1)
位运算O(n + 26) = O(n)O(1)
暴力枚举O(26n) = O(n)O(1)

其中 n 是字符串长度。由于字母数量固定为26,所以空间复杂度为常数级别。

相关题目