《string 专项 10道闯关题》 第1题第一个不重复字符经典1、 输入aabbcdde输出c2、 思路 用数组统计次数 再扫一遍找第一个 1 的3、 代码#includeiostream #includestring using namespace std; int main() { string s; cin s; int cnt[256] {0}; for(char c : s) cnt[(unsigned char)c]; for(char c : s) { if(cnt[(unsigned char)c] 1) { cout c; return 0; } } cout No; }4.⚠️ 陷阱❌ 只统计不遍历顺序❌ 忘记 ASCII 范围5、⏱ 复杂度O(n) 第2题最长无重复子串滑动窗口1、 输入abcabcbb输出32、 思路核心 双指针 记录出现位置3、 代码#includeiostream #includestring using namespace std; int main() { string s; cin s; int last[256]; for(int i 0; i 256; i) last[i] -1; int l 0, ans 0; for(int r 0; r s.size(); r) { if(last[(unsigned char)s[r]] l) l last[(unsigned char)s[r]] 1; last[(unsigned char)s[r]] r; ans max(ans, r - l 1); } cout ans; }4、⚠️ 陷阱❌ 忘记更新左边界❌ 重复字符处理错误5、⏱ 复杂度O(n) 第3题删除所有子串循环 find1、 输入abababc ab输出c2、代码string s, t; cin s t; while(s.find(t) ! string::npos) { s.erase(s.find(t), t.size()); } cout s;3、⚠️ 陷阱❌ 忘记循环删除❌ find 位置变化4、⏱ 复杂度最坏 O(n²) 第4题字符串压缩计数1、 输入aaabbc输出a3b2c12、代码1 按照顺序压缩string s; cin s; for(int i 0; i s.size(); ) { int j i; while(j s.size() s[j] s[i]) j; cout s[i] (j - i); i j; }3、代码2排序后压缩#include iostream #include algorithm #include string using namespace std; int main() { string s; cin s; // 对字符串进行排序使相同字符连续 sort(s.begin(), s.end()); for(int i 0; i s.size(); ) { int j i; // 统计当前字符连续出现的次数 while(j s.size() s[j] s[i]) j; // 输出字符和出现次数 cout s[i] (j - i); i j; // 移动到下一个不同字符的位置 } return 0; }4.⏱ 复杂度O(n) 第5题判断循环位移重点1、 输入abcde cdeab输出YES2、 思路 拼接自己a a3、代码string a, b; cin a b; if((a a).find(b) ! string::npos) cout YES; else cout NO;⚠️ 陷阱❌ 忘记长度相等判断⏱ 复杂度O(n) 第6题最长公共前缀1、 输入flower flow flight输出fl2、代码string a, b, c; cin a b c; string ans ; for(int i 0; i min(a.size(), min(b.size(), c.size())); i) { if(a[i] b[i] b[i] c[i]) ans a[i]; else break; } cout ans;⏱ 复杂度O(n) 第7题翻转单词顺序经典1、 输入I love C输出C love I2、代码1#includesstream string s; getline(cin, s); stringstream ss(s); string word, res ; while(ss word) { res word res; } res.pop_back(); // 删除最后空格 cout res;3、代码2#include iostream #include vector #include string using namespace std; int main() { vectorstring words; // 动态数组存储单词 string word; // 逐个读取单词空格分隔支持多行输入 cout 请输入需要反转的单词每行一个单词按CtrlD结束输入 endl; while (cin word) { words.push_back(word); } // 反向输出从最后一个单词开始 cout \n反转结果 endl; if (!words.empty()) { // 先输出最后一个单词 cout words.back(); // 从倒数第二个单词向前遍历 for (int i words.size() - 2; i 0; --i) { cout words[i]; // 每个单词前加空格 } } cout endl; return 0; }4、⚠️ 陷阱❌ 多空格问题❌ 最后空格处理5、⏱ 复杂度O(n) 第8题判断 anagram异位词1、 输入listen silent输出YES2、 代码string a, b; cin a b; int cnt[256] {0}; for(char c : a) cnt[c]; for(char c : b) cnt[c]--; bool ok true; for(int i 0; i 256; i) { if(cnt[i] ! 0) ok false; } cout (ok ? YES : NO);3、⏱ 复杂度O(n) 第9题最小字典序旋转进阶1、 输入baca输出abac因为切点“bac” a,旋转后为 abac 为所有切点旋转后的最小。2、 思路 枚举所有旋转3、代码string s; cin s; string ans s; for(int i 1; i s.size(); i) { string t s.substr(i) s.substr(0, i); if(t ans) ans t; } cout ans;4、⏱复杂度O(n²) 第10题模拟 find手写1、 输入hello world world输出62、代码string s, t; getline(cin, s); getline(cin, t); for(int i 0; i t.size() s.size(); i) { if(s.substr(i, t.size()) t) { cout i; return 0; } } cout -1;3、⏱代码O(n*m) 最终总结我们现在已经掌握 基础技能✔ find / substr / erase 熟练组合✔ 字符串遍历 修改 核心算法思想 滑动窗口 双指针 计数桶 枚举 模拟