牛客剑指Offer面试题50:第一个只出现一次的字符(面试题2:字符流中第一个只出现一次的字符)

题目描述

请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
输出描述:
如果当前字符流没有存在出现一次的字符,返回#字符。

思路(哈希表)

一.STL中map实现哈希表
哈希表键值对为   字符:出现次数
1.每读取一个字符便保存至字符串中,同时哈希表字符对应字符+1
2.遍历保存的字符串的每个字符,找到某字符对应的哈希表出现次数=1的对应字符即为所求

二.数组实现哈希表
设定一个容量为256的数组存放每个字符在字符流中出现的状态:
(1)各位均初始化为-1,字符未在字符流中出现过
(2)当某字符第一次出现时,对应位occurrence[i]更新为其在字符流中出现的位置index
(3)当某字符再次出现时,对应位occurrence[i]更新为-2
最后遍历occurrence数组,找到数组中元素值(元素值即为某字符最后出现状态)为>=0,且最小的那个元素对应的字符即为所求字符

注:
1.Solution():index(0){ …} 为有参构造函数(将index初始化为0,并在函数体初始化occurrence数字)
2.初始化minIndex为最大的int型数(针对aaaaaaaaaaaaaa…aaaab),第一个未重复出现在最后,它最大的位置索引也只能为最大的int型数(INT_MAX 或 numeric_limits::max() )
参考链接:
numeric_limits::max()函数
INT_MAX 和 INT_MIN

代码1(STL容器map实现哈希表)

//STL容器实现
class Solution
{
public:
  //Insert one char from stringstream
    void Insert(char ch)
    {
        //保存新读取的字符至字符串
        s += ch;
        //该字符出现次数+1
        hashTable[ch]++;
    }
  //return the first appearence once char in current stringstream
    char FirstAppearingOnce()
    {
        char resultChar = '#';
        int sLength = s.size();
        for(int i = 0 ; i < sLength ; ++i)
        {
            if(hashTable[s[i]] == 1)
            {
                resultChar = s[i];
                break;
            }
        }
        return resultChar;
    }
private:
    map<char, int> hashTable; //声明map实现哈希表,存放对应字符出现的个数( 字符:出现次数)
    string s; //用字符串保存读取的字符流
};

代码2(数组实现简单的哈希表)

class Solution
{
public:
    //初始化index和occurrence数组
    Solution():index(0)
    {
        for(int i = 0; i < 256; ++i)
            occurrence[i] = -1;
    }
  //Insert one char from stringstream
    void Insert(char ch)
    {
        //某字符未出现过
         if(occurrence[ch] == -1)
             occurrence[ch] = index;
        //某字符出现过一次
        else if(occurrence[ch] >= 0)
            occurrence[ch] = -2;
        //某字符出现过多次,则不处理,字符流位置游标后移一位
        ++index;
    }
  //return the first appearence once char in current stringstream
    //遍历字符状态数组,寻找元素值最小的且>=0的元素对应的字符即为所求
    char FirstAppearingOnce()
    {
        char resultChar = '#';
        int minIndex = numeric_limits<int>::max();
        //遍历字符状态数组
        for(int i = 0; i < 256 ; ++i)
        {
            //如果找到仅出现一次的数组,且出现位置最靠前的
            if(occurrence[i] >= 0 && occurrence[i] < minIndex)
                //更新对应的字符char 和 最小出现位置minIndex
            {
                resultChar = (char)i; //位置索引强制转换为对应char型字符
                minIndex = occurrence[i];
            }
        }
        return resultChar;
    }

private:
    int index; //字符流位置游标:用于索引某字符出现的位置
    int occurrence[256];  //保存各个字符最后状态的数组
};
发布了65 篇原创文章 · 获赞 0 · 访问量 2032

猜你喜欢

转载自blog.csdn.net/ljmiiianng/article/details/103836595
今日推荐