牛客解题思路:字符流中第一个不重复的字符 纠错记录

字符流中第一个不重复的字符


思路:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符 “go” 时,第一个只出现一次的字符是 “g”。当从该字符流中读出前六个字符“google" 时,第一个只出现一次的字符是 “l”。

这一题思路是比较清晰的,首先我们需要一个数组来记录各个元素出现的频率,还需要用一种数据结构记录各个字符出现的顺序,这个数据结构最合适的无疑是队列,那么代码就好写了:

private int[] cnts = new int[26];
private Queue<Character> queue = new LinkedList<>();
public void Insert(char ch) {
    cnts[ch - 'a']++;
    queue.add(ch);
    while (!queue.isEmpty() && cnts[queue.peek() - 'a'] > 1)
        queue.poll();
}
public char FirstAppearingOnce() {
    return queue.isEmpty() ? '#' : queue.peek();
}

但是这就有一个问题,题目中并没有说出现的字符一定是小写呀,小小的吐槽一下剑指offer的题目,总是表述不清呀,提供的题例也太少了ε(┬┬﹏┬┬)3但是实际上应该还是怪我没有考虑周密,所以这一题给我最大的教训是,遇到这种字符没有指定大小写的时候,直接使用:

int[] cnts = new int[256];

然后存入字符的时候只需要:

cnts[ch]++;

即可,又方便又不容易出错,希望我下次记住不犯这种低级错误(●ˇ∀ˇ●)
下面给出正确代码:

private int[] cnts = new int[256];
private Queue<Character> queue = new LinkedList<>();

public void Insert(char ch) {
    cnts[ch]++;
    queue.add(ch);
    while (!queue.isEmpty() && cnts[queue.peek()] > 1)
        queue.poll();
}

public char FirstAppearingOnce() {
    return queue.isEmpty() ? '#' : queue.peek();
}

还可以用LinkedHashMap,可以保存输入的顺序:

//Insert one char from stringstream
Map<Character,Integer> map = new LinkedHashMap<>();
public void Insert(char ch)
{
    map.put(ch,map.getOrDefault(ch,0)+1);
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
    Iterator iter = map.keySet().iterator();  
    while (iter.hasNext()) {
        Character key = (Character)iter.next();      
        int val = map.get(key);   
        if(val>1){
            iter.remove();
        }else{
            return key;
        }
    }
    return '#';
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值