1 条题解
-
0
📝 题目大意
给定一个仅由小写英文字母组成的字符串 ,判断它是否为"好字符串"。好字符串的定义是:对于所有整数 ,在 中恰好出现 次的字符种类数必须为 或 (不能为其他值)。
💡 解题思路
-
题目分析:字符串长度 ,只有 种小写字母,数据范围极小。核心任务是统计每种字符的出现次数,再统计"每种出现次数对应了多少种字符",最后验证这个"种类数"是否只可能是 或 。
-
算法推导:
- 第一步——字符频率统计:用大小为 的数组
cnt(下标0~25对应a~z)统计每个字符在 中出现的次数。遍历 的每个字符c,执行cnt[c - 'a']++。 - 第二步——出现次数归类:题目关心的是"出现次数 对应了多少种字符"。因此再开一个数组
freqCount,大小为 (因为 ,任何字符出现次数不会超过 )。遍历 个字母,若某个字母出现过(cnt[i] > 0),则freqCount[cnt[i]]++,表示"出现次数恰好为cnt[i]的字符种类数"加一。 - 第三步——合法性检查:遍历 从 到 ,检查
freqCount[i]。若freqCount[i]既不是 也不是 ,则不符合好字符串定义,直接输出No并结束。若全部检查通过,输出Yes。
- 第一步——字符频率统计:用大小为 的数组
-
边界与细节:
- 由于 长度最小为 ,不会出现空串。
- 出现 次的字符(即字符串中未出现的字母)不参与第二步的统计,因为只统计
cnt[i] > 0的字母。 freqCount数组大小至少为 ( 最大值 ),用vector<int>(101, 0)初始化即可。- 注意:题目要求的是"恰好出现 次的字符种类数",不是字符本身。不要混淆两层统计。
⏱️ 复杂度分析
- 时间复杂度:。遍历字符串统计频率 ,遍历 个字母 ,遍历 个可能的出现次数 ,三者线性叠加。由于 ,常数极小。
- 空间复杂度:。
cnt数组大小 ,freqCount数组大小 ,均为常数级。
💻 标准代码 (C++)
#include <iostream> #include <string> #include <vector> using namespace std; int main() { string S; cin >> S; // cnt[i]:字母 i 在 S 中出现的次数(0=a, 1=b, ..., 25=z) vector<int> cnt(26, 0); for (char c : S) { cnt[c - 'a']++; } // freqCount[i]:出现次数恰好为 i 的字符种类数 vector<int> freqCount(101, 0); // 长度最大100,出现次数最大100 for (int i = 0; i < 26; i++) { if (cnt[i] > 0) { freqCount[cnt[i]]++; } } // 检查每个出现次数 i 对应的种类数是否为 0 或 2 for (int i = 1; i <= 100; i++) { if (freqCount[i] != 0 && freqCount[i] != 2) { cout << "No" << endl; return 0; } } cout << "Yes" << endl; return 0; } -
- 1
信息
- ID
- 787
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者