描述 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。 后台会用以下方式调用Insert 和 FirstAppearingOnce 函数 string caseout = ""; 1.读入测试用例字符串casein 2.如果对应语言有Init()函数的话,执行Init() 函数 3.循环遍历字符串里的每一个字符ch { Insert(ch); caseout += FirstAppearingOnce() } 2. 输出caseout,进行比较。 返回值描述: 如果当前字符流没有存在出现一次的字符,返回#字符。 示例1 输入: "google" 返回值: "ggg#ll" 题目简述 在集合中不断加入字符,对于新的集合,找到第一个只出现过一次的字符,若没有则返回 # 。 算法一: 哈希表+字符串 时间复杂度:O(N) 思路: 每个字符都有与之对应的ASCII码,可直接与数组下标对应,我们用数组a统计每个字符出现的次数。 Insert():每次插入一个元素都将它加入字符串中,然后将a数组加 1 。 FirstAppearingOnce():从 t 开始遍历字符串,找到第一个只出现过一次的字符 , 用 t 标记下这个位置,并返回它的字符串 。 代码: class Solution{public: //Insert one char from stringstream int a[1000]={0}; queue<char> q; string s; int t=0; void Insert(char ch) { s+=ch; a[ch]++; } //return the first appearence once char in current stringstream char FirstAppearingOnce() { for(int i=t;i<s.size();i++){ if(a[s[i]]==1){ t=i; return s[i]; } } return '#'; }}; 算法二:哈希表+队列 时间复杂度:O(N) 思路: 每个字符都有与之对应的ASCII码,可直接与数组下标对应,我们用数组a统计每个字符出现的次数。 Insert():用数组a记录字符出现的次数,将未出现过的字符加入队列中,然后不断判断队首字符,是否出现过多次,若有多次则弹出队首字符,否则停止,这样保证了队首始终为只出现过一次的字符。 FirstAppearingOnce():直接取队首元素即可,若队列为空,则返回#。 图解: 代码: class Solution{public: //Insert one char from stringstream int a[1000]={0}; queue<char> q; int t=0; void Insert(char ch) { a[ch]++;//统计元素出现的次数 if(a[ch]==1) q.push(ch); while(!q.empty()){ //弹出出现多次的字符,保证队首始终是只出现过一次的字符 if(a[q.front()]>1) q.pop(); else break; } } //return the first appearence once char in current stringstream char FirstAppearingOnce() { if(!q.empty()){ return q.front(); } return '#'; }};