剑指offer面试题牛客_字符串_字符流中第一个不重复的字符(java版)

welcome to my blog

剑指offer面试题牛客_字符串_字符流中第一个不重复的字符(java版):

题目描述

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

思路

  • ascii码一共128个, 空格是第一个能输入的字符, 对应的ascii是32
  • 创建一个长度为128的数组,根据ascii码统计字符出现的次数 ch - ’ ’ + 32就是字符ch对应的ascii码
  • 出现过一次的字符append到sb中, 重复出现的字符不再添加到sb中,但是仍会增加出现次数
  • 遍历sb的字符, 返回出现次数为1的字符
第三次做, 提到字符就要想到只有128个, 实际上其中只有32到127这95个是非控制字符, 可以创建一个长为95的数组记录次数; 还要创建的变量记录位置, 使用StringBuilder比链表方便; 本题就是想要清楚怎么记录次数以及怎么记录位置
public class Solution {
    //Insert one char from stringstream
    int[] arr = new int[128]; //记录次数
    StringBuilder sb = new StringBuilder();//记录位置
    public void Insert(char ch)
    {
        sb.append(ch);
        arr[ch]++;
    }
  //return the first appearence once char in current stringstream
    public char FirstAppearingOnce()
    {
        for(int i=0; i<sb.length(); i++){
            if(arr[sb.charAt(i)]==1)
                return sb.charAt(i);
        }
        return '#';
    }
}
第二次做, 使用长度为95的数组代替哈希表
import java.util.LinkedList;
public class Solution {
    //Insert one char from stringstream
    //32~126是非控制字符, 共95个
    //数组中索引0记录空格出现的次数
    char[] arr = new char[95];
    LinkedList<Character> ll = new LinkedList<>();
    public void Insert(char ch)
    {
        //每个字符的索引都是固定的
        int index = ch - ' ' ; 
        arr[index]++;
        ll.add(ch);
    }
  //return the first appearence once char in current stringstream
    public char FirstAppearingOnce()
    {
        if(ll.isEmpty())
            return '#';
        while(! ll.isEmpty()){
            int index = ll.peek() - ' ';
            if(arr[index]==1)
                return ll.peek();
            ll.poll();
        }
        //队列中没有只出现一次的字符
        return '#';
    }
}
第二遍做, 创建一个队列一个哈希表,队列保存出现一次的字符,哈希表记录字符出现的次数; 这个方法空间消耗比较大, 其实可以利用字符种类有限(128个?)的特点,使用数组记录次数
import java.util.LinkedList;
import java.util.HashMap;

public class Solution {
    //Insert one char from stringstream
    public LinkedList<Character> q = new LinkedList<>();
    public HashMap<Character, Integer> hm = new HashMap<>();
    public void Insert(char ch)
    {
        if(hm.containsKey(ch)){
            hm.put(ch, hm.get(ch)+1);
            if(q.contains(ch))
                q.remove(q.indexOf(ch));
        }
        else{
            hm.put(ch, 0);
            q.add(ch);
        }
    }
  //return the first appearence once char in current stringstream
    public char FirstAppearingOnce()
    {
        return q.isEmpty() ? '#' : q.peek();
    }
}
import java.util.ArrayList;
public class Solution {
    int[] arr = new int[128]; // 利用了默认初始化为0的特点
    StringBuffer sb = new StringBuffer();
    //Insert one char from stringstream
    public void Insert(char ch)
    {
        int index = ch - ' ' + 32;
        arr[index]++;
        if(arr[index]==1)
            sb.append(ch);
    }
  //return the first appearence once char in current stringstream
    public char FirstAppearingOnce()
    {
        if(sb.length() == 0 ) return '#';
        int index;
        for(int i=0; i<sb.length(); i++){
            index = sb.charAt(i) - ' ' + 32;
            if(arr[index]==1) 
                return sb.charAt(i);
        }
        return '#';
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值