字符流中第一个只出现一次的字符
请实现一个函数用来找出字符流中第一个只出现一次的字符。
例如,当从字符流中只读出前两个字符”go”时,第一个只出现一次的字符是’g’。
当从该字符流中读出前六个字符”google”时,第一个只出现一次的字符是’l’。
如果当前字符流没有存在出现一次的字符,返回#字符。
样例
输入:“google”
输出:“ggg#ll”
解释:每当字符流读入一个字符,就进行一次判断并输出当前的第一个只出现一次的字符。
方案一:
利用队列和哈希表
队列里始终是第一次出现次数为一的字符,如果加入的字符次数大于一,如果他不是队首就不插入,如果他是队首,他又次数大于一就把队首弹掉,并且不插入这个重复的数
否则都插入
HashMap <Character,Integer> map = new HashMap<>();
Queue<Character>queue = new LinkedList<>();
public void insert(char ch){
if(!map.containsKey(ch)){
map.put(ch,1);
}else{
int count = map.get(ch)+1;
map.put(ch,count);
}
if(map.get(ch)>1){
while(!queue.isEmpty()&&map.get(queue.peek())>1){
queue.poll();
}
}else{
queue.offer(ch);
}
}
//return the first appearence once char in current stringstream
public char firstAppearingOnce(){
if(!queue.isEmpty()){
return queue.peek();
}else{
return '#';
}
}
方法二:
手写一个数组来实现哈希表,每个char 有8位,可以用256长的数组来表示每个字符,初始化它们的值都是-1,如果出现了一次以上不管几次它们的值都是-2,这里设一个index变量 初始化为0,如果有出现过一次的第一个字符他的index就是0,再判断如果第二个字符出现了也是一次,就index++给第二个字符的数组下表,最后统计的就是数组值>=0,并且index小的字符
class Solution {
private int index;
private int[] occ;
public Solution(){
index = 0;
occ = new int[256];
for(int i = 0; i <256;i++){
occ[i] = -1;
}
}
//Insert one char from stringstream
public void insert(char ch){
if(occ[(int)ch]==-1){
occ[(int)ch]=index;
}else if(occ[(int)ch]>=0){
occ[(int)ch]=-2;
}
index++;
}
//return the first appearence once char in current stringstream
public char firstAppearingOnce(){
int minIndex = Integer.MAX_VALUE;
char ch = '#';
for(int i = 0 ;i<256;i++){
if(occ[i]>=0&&occ[i]<minIndex){
ch = (char)i;
minIndex = occ[i];
}
}
return ch;
}
}