问题描述:
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
案例:
s = "leetcode" 返回 0. s = "loveleetcode", 返回 2.
注意事项:您可以假定该字符串只包含小写字母。
基本思路:
建立一个字符到该字符出现个数统计的映射,
然后找出第一个个数统计为1的元素。
有一点要尤为注意:
我们都知道哈希表是可以遍历的。
但是很遗憾,unordered_map内部是使用哈希表进行存储的,他是hash(法语,被打乱的)的。也就是说,是没有顺序的。
先插入的键值对很有可能不会最先访问。
所以不要寄希望于遍历hashmap得到第一个value为1的元素。
这里有两个解决方法:
- 在统计出现个数的时候顺便记录索引,用pair<int, int>的类型来作为value
- 最后再从头扫描字符串,一碰到value为1的,立即返回。
AC代码:
class Solution {
public:
int firstUniqChar(string s) {
map<char, pair<int, int>> hashmap; // 第一个int统计次数,第二个int统计索引
for (int i = 0; i < s.size(); ++i) {
++hashmap[s[i]].first;
hashmap[s[i]].second = i;
}
// 特别注意由于是哈希实现的,这里遍历hashmap不能保证任何顺序
int min = INT_MAX;
for (auto it = hashmap.begin(); it != hashmap.end(); ++it) {
if (it->second.first == 1) {
if (it->second.second < min) min = it->second.second;
}
}
return (min == INT_MAX)? -1 : min;
}
};
class Solution {
public:
int firstUniqChar(string s) {
int len = s.length();
if(len < 1){
return -1;
}
vector<int> answer(26,0);
for(int i = 0;i < len;i++){
answer[s[i] - 'a']++;
}
for(int i = 0;i < len;i++){
if(answer[s[i] - 'a'] == 1){
return i;
}
}
return -1;
}
};