题目描述:
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写)
用map实现字符统计,将字符串中所有字符加进map中,再根据字符的顺序,依次查找每一个字符出现的个数。
方法一:用map统计字符个数
class Solution {
public:
int FirstNotRepeatingChar(string str) {
int len=str.size();
map<char,int>mp;
for(int i=0;i<len;i++)
mp[str[i]]++;
for(int i=0;i<len;i++)
{
if(mp[str[i]]==1)
return i;
}
return -1;
}
};
方法二:用数组统计字符个数
将统计结果放在一个数组中,字符对应的ASCII为数组下标,数组中元素为该元素出现的次数。
A-Z的ASCII码的对应的为41-90
a-z的ASCII码的对应的为97-122
class Solution {
public:
int FirstNotRepeatingChar(string str) {
int len=str.size();
int a[100]={0};
for(int i=0;i<len;i++)
a[str[i]-'A']++;
for(int i=0;i<len;i++)
if(a[str[i]-'A']==1)
return i;
return -1;
}
};
对ASCII范围没有概念,还有一种方法,26个英文字符算上大小写,一共52个字符,建一个大小为52的数组,每个字符对应一个下标。
class Solution {
public:
int FirstNotRepeatingChar(string str) {
int len=str.size();
int a[52]={0};
for(int i=0;i<len;i++)
{
if(str[i]>='a'&&str[i]<='z')
a[str[i]-'a']++;
else
a[str[i]-'A'+26]++;
}
for(int i=0;i<len;i++)
{
if(str[i]>='a'&&str[i]<='z')
{
if(a[str[i]-'a']==1)
return i;
}
else
{
if(a[str[i]-'A'+26]==1)
return i;
}
}
return -1;
}
};
方法三:用基于hash的map统计字符个数
思路:先统计每个字符出现的次数,然后遍历字符,找到第一个只出现一次的字符。
1、不要使用基于二叉树的map,会增加复杂度;
2、c++的基于hash的map是unordered_map;
3、也可以用数组实现一个简单的hash map;
class Solution {
public:
int FirstNotRepeatingChar(string str) {
int len=str.size();
int hash[256]={0};
for(int i=0;i<len;i++)
hash[str[i]]++;
for(int i=0;i<len;i++)
if(hash[str[i]]==1)
return i;
return -1;
}
};