第一个只出现一次的字符
题目分析
面试题50-1:在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).
题目分析
1.使用哈希表来记录每个字符出现的次数,因为字符charchar为8位,总共有256个值,所有哈希表有256个元素,其中把字符的ASCIIASCII码作为哈希表的键值,而对应键值储存的是该字符出现的次数。
2.那么对给定的字符串进行两次遍历,第一遍收集信息,即统计每个字符串出现了多少次。第二次查找第一个出现一次的字符,即碰到第一个只出现了一次的字符就进行输出。
哈希表是一种常用的数据结构,这里我们使用哈希表把一个字符映射成一个数字。在STL中,map和unordered_map就实现了哈希表的功能,同样使用数组/vector来实现简单的哈希表。
- 注释版
class Solution {
public:
int FirstNotRepeatingChar(string str){
int strSize = str.size();
//处理错误输入
if(strSize <= 0)return -1;
//处理特殊输入
if(strSize == 1)return 0;
//使用vector做一个哈希表,记录每个字符出现的次数,全部初始化为0
vector<int> hashTable(256,0); //map<char,int> hashmap; map的value为int时,默认初始化为0
//范围for循环对输入字符串进行第一次遍历,统计每一种字符出现的次数
for(auto s:str)
//s对应的ASCII码作为键,s出现的次数作为值,组成键值对
hashTable[s]++; //string自动提升转换为int型(ASCII码),
//对输入字符串进行第二次遍历
for(int i = 0;i != strSize;i++){ //第二次遍历str(不是hashmap),根据str中的字符在hashmap中寻找值(次数)
if(hashTable[str[i]] == 1)
return i;
}
return -1;
}
};
- 无注释版
class Solution {
public:
char firstUniqChar(string s) {
if(s.size()==0)
return ' ';
map<char,int> mp;
for(int i=0;i<s.size();++i){
//if(mp[s[i]]==0)//没出现过
// mp[s[i]]=1;
//else
++mp[s[i]];
}
/*
for(auto s1 : s)
hashmap[s1]++;
*/
for(int i=0;i<s.size();++i){
if(mp[s[i]]==1)
return s[i];
}
return ' ';
}
};
总结
- 范围for循环的使用
- 隐形的类型转换,string提升为int(ASCII码)
- 建立一个256大小的哈希表,是因为:首先,建立一个128大小的哈希表即可。然后解释:字符在计算机中以ASCII码的形式存储,当字符作为数组下标时,其表示的下标值为该字符的ASCII码的十进制值。而ASCII码由8位表示,只有后面7位起作用,2^7为128,因此ASCII码共有128个字符,十进制范围为0127.)(建立256大小是因为char占一个字节(8位),无符号范围为0255,有符号就为-128~127。)
- map的value为int时,默认初始化为0
字符流中第一个不重复的字符
题目分析
面试题50-2:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
思路分析
class Solution{
public:
//Insert one char from stringstream
string s;
//vector <int> hash(256,0); //报错,不知为何?
int hash[256]={0}; //如果只对部分元素初始化,剩下的未显式初始化的元素,将自动被初始化为零;
void Insert(char ch){
s += ch;
hash[ch]++; //hash数组记录每个字符出现的次数
}
//return the first appearence once char in current stringstream
//遍历输出的流,根据hash数组由字符找到字符出现次数
char FirstAppearingOnce(){
int size=s.size();
for(int i=0;i<size;++i){
if(hash[s[i]]==1)
return s[i];
}
return '#';
}
};