❓ 剑指 Offer41.2 字符流中第一个不重复的字符
难度:中等
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符 "go"
时,第一个只出现一次的字符是 "g"
。当从该字符流中读出前六个字符 “google"
时,第一个只出现一次的字符是 "l"
。
如果当前字符流没有存在出现一次的字符,返回 #
字符。
数据范围:字符串长度满足 1 ≤ n ≤ 1000 1≤n≤1000 1≤n≤1000 ,字符串中出现的字符一定在 ASCII 码内。
进阶:空间复杂度$O(n) $ ,时间复杂度 O ( n ) O(n) O(n)。
后台会用以下方式调用 Insert
和 FirstAppearingOnce
函数
string caseout = “”;
1.读入测试用例字符串casein
2.如果对应语言有Init()函数的话,执行Init() 函数
3.循环遍历字符串里的每一个字符ch {
Insert(ch);
caseout += FirstAppearingOnce()
}
2. 输出caseout,进行比较。
示例1
输入:“google”
返回值:“ggg#ll”
示例2
输入:“abcdee”
返回值:“aaaaaa”
💡思路:
-
由字符串中出现的字符一定在 ASCII 码内,所以可以使用一个大小为 128 的数组
cnts
来统计每个字符出现的次数; -
另设一个队列来存储到达的字符,并在每次有新的字符从字符流到达时,移除队列头部那些出现次数不再是一次的元素。
- 因为队列是先进先出顺序,因此队列头部的元素为第一次只出现一次的字符。
注意:
在 C++ 中
private:
vector<int> cnts(128);
//意欲申请长度为5的vector
编译器无法区分该语句是成员 变量声明 还是 成员函数声明。
- 解决办法是:消除歧义。
- 利用vector的赋值构造函数
vector<int> cnts = vector<int> (128, 0);
🍁代码:(C++、Java)
C++
class Solution
{
private:
vector<int> cnts = vector<int> (128, 0);
queue<char> q;
public:
//Insert one char from stringstream
void Insert(char ch) {
cnts[ch]++;
q.push(ch);
while(!q.empty() && cnts[q.front()] > 1){
q.pop();
}
}
//return the first appearence once char in current stringstream
char FirstAppearingOnce() {
return q.empty() ? '#' : q.front();
}
};
Java
🚀 运行结果:
🕔 复杂度分析:
- 时间复杂度: O ( n ) O(n) O(n),每次插入字符都是 O ( 1 ) O(1) O(1),每次查询需要遍历字符串 O ( n ) O(n) O(n)。
- 空间复杂度:
O
(
n
)
O(n)
O(n),字符一定在ASCII范围内,因此数组
cnts
大小为常数,但是记录的字符的队列q
为还是为n
。
题目来源:牛客网。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!