LeetCode 每日一题笔记 日期:2026.05.27 题目:3121. 统计特殊字母的数量 II

LeetCode 每日一题笔记

0. 前言

  • 日期:2026.05.27
  • 题目:3121. 统计特殊字母的数量 II
  • 难度:中等
  • 标签:字符串、数组、哈希

1. 题目理解

问题描述 :

给你一个字符串 word。

如果某个小写字母在字符串中所有出现的位置都在对应大写字母出现之前 ,那么这个字母就是特殊字母 。

返回字符串中特殊字母的数量。

示例:

输入:word = "AbBCab"

输出:1

2. 解题思路

核心观察

  • 小写字母必须全部出现在大写字母第一次出现之前。
  • 记录每个字符第一次出现 和最后一次出现的位置。
  • 判断:小写字母最后一次出现的位置 < 大写字母第一次出现的位置。

算法步骤

  1. 遍历字符串,记录每个字符的首次和末次出现位置。
  2. 遍历 26 个字母,检查是否满足条件。
  3. 统计满足条件的字母数量。

3. 代码实现

java 复制代码
public class Solution {
    public int numberOfSpecialChars(String word) {
        int[][] arr = new int[26][2];

        int res = 0;
        for (int i = 0; i < word.length(); i++) {
            char cur = word.charAt(i);
            //处理小写
            if (cur <= 'z' && cur >= 'a') {
                int num = cur - 'a';
                if (arr[num][1] != 0) {
                    arr[num][0] = 0;
                } else arr[num][0] = 1;
            }
            //处理大写
            if (cur <= 'Z' && cur >= 'A') {
                int num = cur - 'A';
                arr[num][1] = 1;

                
            }
        }
        for (int i = 0; i < 26; i++) {
            if (arr[i][0] == 1 && arr[i][1] == 1) {
                res++;
            }
        }

        return res;
    }
}

4. 代码优化说明

java 复制代码
class Solution {
public int numberOfSpecialChars(String word) {
// 记录每个字符第一次出现的位置
int[] first = new int['z' + 1];
// 记录每个字符最后一次出现的位置
int[] last = new int['z' + 1];

// 遍历字符串,填充 first 和 last 数组
for (int i = 1; i <= word.length(); ++i) {
    int j = word.charAt(i - 1);
    if (first[j] == 0) {
        first[j] = i;
    }
    last[j] = i;
}

int ans = 0;
// 遍历 26 个字母
for (int i = 0; i < 26; ++i) {
    // 小写字母
    int a = 'a' + i;
    // 大写字母
    int b = 'A' + i;
    // 判断:小写字母存在 && 小写最后一次 < 大写第一次
    if (last[a] > 0 && last[a] < first[b]) {
        ++ans;
    }
}
return ans;
}
}

5. 复杂度分析

  • 时间复杂度 :O(n+26)O(n + 26)O(n+26)
    一次遍历字符串 + 遍历26个字母。
  • 空间复杂度 :O(1)O(1)O(1)
    固定大小的数组,常数空间。

6. 总结

  • 核心:记录字符首次/末次位置,判断位置关系。
  • 优化思路:用位置判断替代复杂的状态标记,逻辑更清晰。
  • 关键:小写全部在大写前面 → last[小写] < first[大写]。
相关推荐
I_belong_to_jesus3 小时前
C++关于分支预测的优化1
开发语言·c++·算法
Rabitebla4 小时前
【Linux】进程控制(十二) 自定义 Shell(二):内建命令与进程工作目录管理
linux·c++·笔记·学习·bash
坤坤子吖9 小时前
Linux网络编程:TCP 粘包与半包问题,如何正确处理 TCP 流式数据?
linux·服务器·网络·笔记·网络协议·学习
Code_Solitude10 小时前
C语言动态内存 + 柔性数组 + 数组名退化
c语言·算法·柔性数组
上海潭龙东海科技有限公司10 小时前
客运站管控之动态孪生技术方案(新增一屏管控模块
数据仓库·人工智能·算法·重构·动态规划
文丑颜不良啊11 小时前
LeetCode2821~2840题目解析
java·leetcode
YLCHUP13 小时前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论
思麟呀13 小时前
背包DP(01背包+完全背包)
c++·算法
笑容掩饰我的失落14 小时前
区块链从小白到精通(七):Solidity 语法精讲——数据类型、函数、修饰器与事件
算法·区块链·php·智能合约·哈希算法