剑指offer第二版-50.2.字符流中第一个只出现一次的字符

本系列导航:剑指offer(第二版)java实现导航帖

面试题50.2:字符流中第一个只出现一次的字符

题目要求:
找出字符流中第一个只出现一次的字符。例如,当从字符流google中只读出前两个字符go时,第一个只出现一次的字符是g;当读完google时,第一个只出现一次的字符是l。

解题思路:
此题的关键在于“字符流”。因此最好能够记住在哪个位置出现了哪个字符,从而可以完成每读到一个字符,就能动态更新到目前为止第一个出现一次的字符。此题同样使用了长度为256的int数组作为哈希表,用字符的ascii码值作为表的键值,当字符仅出现了一次,就把字符的位置作为哈希表的值,如果没有出现则值为-1,如果出现的次数大于1则哈希表对应的值为-2。
当想要知道到某一位置时第一个出现一次的字符,可以通过扫描该哈希表,找到大于等于0的值中的最小值,该值所对应的字符就是当前状态第一个出现一次的字符。

package chapter5;

/**
 * Created with IntelliJ IDEA
 * Author: ryder
 * Date  : 2017/8/13
 * Time  : 16:41
 * Description:字符流中第一个只出现一次的字符
 **/
public class P247_FirstNotRepeatingCharInStream {
    public static class CharStatistics{
        private int[] times;
        private int index;
        public CharStatistics(){
            index = 0;
            times = new int[256];
            //-1表示未出现,>=0表示出现的位置且仅出现一次,-2表示出现两次及以上
            for(int i=0;i<256;i++)
                times[i] = -1;
        }
        public void insert(char ch){
            if(times[ch]==-1)
                times[ch] = index;
            else
                times[ch] = -2;
            index++;
        }
        public char find(){
            int minIndex = 256;
            char ret = '\77'; //若没有只出现一次的字符,显示\77,即?
            for(int i=0;i<256;i++){
                if(times[i]>=0 && times[i]<minIndex) {
                    minIndex = times[i];
                    ret = (char)i;
                }
            }
            return ret;
        }
    }
    public static void main(String[] args){
        String str = "google";
        CharStatistics charStatistics = new CharStatistics();
        for(int i=0;i<str.length();i++){
            charStatistics.insert(str.charAt(i));
            System.out.print(charStatistics.find());
        }
    }
}

运行结果

ggg?ll

推荐阅读更多精彩内容