题目描述
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).
我的思路:
第一次遍历string,用一个map记录每个字符出现的次数
第二次遍历map,找到次数为1的字符
第三次遍历string,找到该字符出现的位置。
问题:
map中键值对的顺序并不是按插入顺序来的,最后会按key值升序排列。所以找到的出现次数为1的字符可能不是第一个。
#include<map>
#include<iterator>
class Solution {
public:
int FirstNotRepeatingChar(string str) {
int len = str.size();
map<char, int> mymap;
map<char, int>::iterator iter;
char firstChar;
int firstCharPos = -1;
if(len == 0) return -1;
for(int i = 0; i < len; i++)
{
iter = mymap.find(str[i]);
if(iter != mymap.end())
mymap[str[i]]++;
else
mymap.insert(pair<char, int>(str[i], 1));
}
bool flag = false;
for(iter = mymap.begin(); iter != mymap.end(); iter++)
{
if(iter->second == 1)
{
firstChar = iter->first;
flag = true;
break;
}
}
if(flag)
{
for(int i = 0; i < len; i++)
{
if(str[i] == firstChar)
firstCharPos = i;
}
}
return firstCharPos;
}
};
改进
其实没必要遍历三次,只需遍历两次。第二次遍历string,看该字符出现的次数是不是为1.。这样找到的第一个字符就是第一个出现次数为1的字符。
#include<map>
#include<iterator>
class Solution {
public:
int FirstNotRepeatingChar(string str) {
int len = str.length();
map<char, int> mymap;
map<char, int>::iterator iter;
char firstChar;
if(len == 0) return -1;
for(int i = 0; i < len; i++)
{
iter = mymap.find(str[i]);
if(iter != mymap.end())
mymap[str[i]]++;
else
mymap.insert(pair<char, int>(str[i], 1));
}
for(int i = 0; i < len; i++)
{
if(mymap[str[i]] == 1)
{
firstChar = str[i];
return i;
}
}
return -1;
}
};
书上代码
书上代码用一个大小为256(一个字符用8bit表示)的数组实现了hashmap,与直接用map在查找某键值的时间效率上有不同么?数组实现的话查找与修改都是O(1)。