字符流中第一个只出现一次的字符

字符流中第一个只出现一次的字符

请实现一个函数用来找出字符流中第一个只出现一次的字符。

例如,当从字符流中只读出前两个字符”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;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值