题目描述:
请实现一个函数用来找出字符流中第一个只出现一次的字符。
例如,当从字符流中只读出前两个字符”go”时,第一个只出现一次的字符是’g’。
当从该字符流中读出前六个字符”google”时,第一个只出现一次的字符是’l’。
如果当前字符流没有存在出现一次的字符,返回#字符。
样例
输入:"google"
输出:"ggg#ll"
解释:每当字符流读入一个字符,就进行一次判断并输出当前的第一个只出现一次的字符。
算法1:
class Solution{
vector<int>cnt;
int index ;
public:
Solution()
{
index = 0;
for(int i=0; i<256; i++)
{
cnt.push_back(-1);
}
}
//Insert one char from stringstream
void insert(char ch){
if(cnt[ch]==-1)
cnt[ch] = index;
else if(cnt[ch] >=0)
cnt[ch] = -2;
index ++;
}
//return the first appearence once char in current stringstream
char firstAppearingOnce(){
int Max = INT_MAX;
char ch = '#' ;
for(int i=0; i<cnt.size(); i++)
{
if(cnt[i] < Max && cnt[i]>=0)
{
Max = cnt[i];
ch = (char)i;
}
}
return ch;
}
};
算法2:
使用 hash 映射 和队列,
- 字符流中出现一次的字符都会存在队列中,刚好可以利用队列的先进先出的特性。如果队列不为空,则返回队头元素,为空,则返回 ‘#’
- 将字符在hash的对应位置加一计数,然后检查这个元素的个数是否满足第一次出现,若满足则直接插入队列中,否则,检查队头元素是否是字符串流中的第一个字符,如果不是,则弹出,直到满足队列为空或者队头元素只出现了一次。
class Solution{
public:
//Insert one char from stringstream
unordered_map<char, int>count;
queue<char>q;
void insert(char ch){
count[ch] ++ ;
if(count[ch] == 1)
{
q.push(ch);
}
else
{
while(q.size() > 0 && count[q.front()] > 1)
q.pop();
}
}
//return the first appearence once char in current stringstream
char firstAppearingOnce(){
if(!q.empty())
return q.front();
else
return '#';
}
};