字符流中第一个不重复的字符
问题
题目描述
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
输出描述:
如果当前字符流没有存在出现一次的字符,返回#字符。
思路一:使用HashMap暴力法存储所有字符
使用HashMap,
key
为字符
,value
为字符出现的次数
每次取的时候按照顺序遍历字符串,求取在Map中出先的次数
思路二:使用队列存储不重复元素
链接:https://www.nowcoder.com/questionTerminal/00de97733b8e4f97a3fb5c680ee10720?answerType=1&f=discussion来源:牛客网
字符出现顺序的判断(第一个字符):
这里就是改进的关键之处了,容易发现,字符流中不重复的字符可能同时存在多个,我们只要把这些 “不重复字符” 保存起来就可以,而无需保存那些重复出现的字符,而为了维护字符出现的顺序,我们使用队列(先进先出)这一结构,先出现的不重复字符先输出:
- 入队:获取字符流中的一个字符时,当我们判断它是不重复时,将它加入队列;
- 输出/出队:注意,因为队列中存储的 “不重复字符” 在一系列的流读取操作后,随时有可能改变状态(变重复),所以,队列中的字符不能直接输出,要先进行一次重复判断,如果发现队头字符已经重复了,就将它移出队列并判断新的队头,否则,输出队头的值;
package C字符串;
import java.util.LinkedList;
import java.util.Queue;
/**
* @Author Zhou jian
* @Date 2020 ${month} 2020/2/19 0019 20:00
*
* 请实现一个函数用来找出字符流中第一个只出现一次的字符。
* 例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
*/
public class Problem3 {
int[] charCnt = new int[128];//128中字符用尽
//字符流中不重复的字符可能存在多个
//我们只要把这些“不重复字符保存起来,而无须保存那些重复出现的字符“,
// 而为了维护字符出现的顺序,我们使用队列(先进先出)这一结构,先出现的不重复字符先输出
//
Queue<Character> queue = new LinkedList<>();
public static void main(String[] args) {
}
//Insert one char from stringstream
public void Insert(char ch)
{
if(charCnt[ch]++==0){
queue.add(ch);
}
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
Character CHAR = null;
char c =0;
while((CHAR= queue.peek())!=null){
c = CHAR.charValue();
if(charCnt[c]==1){//判断是否脱单,没脱单则输出
return c;
}else{
queue.remove();//脱单则移除队列
}
}
return '#';//队列为空返回#
}
}