本题目对应leetcode387题,在查看官方题解之后,记录总结如下:
题目:
给定一个字符串,小写字母a-z,帮我找到第一个不重复出现的字母,并返回它的下标
解法
Hash
定义一个数组,先遍历一遍,存储每个字母出现次数,然后再进行一次遍历,查看哪个字母的出现次数不超过1,就直接返回。
class Solution {
public:
int firstUniqChar(string s) {
int cnt=-1;
int a[27]={0};
for(int i=0;i<s.size();i++){
a[s[i]-'a']++;
}
for(int i=0;i<s.size();i++){
if(a[s[i]-'a']==1)
{
cnt=i;
break;
}
}
return cnt;
}
};
队列
题解来源于Leetcode官方,我在上面加了部分注释:
class Solution {
public:
int firstUniqChar(string s) {
unordered_map<char, int> position; // 存储字符及其首次出现的索引
queue<pair<char, int>> q; // 按顺序存储可能的唯一字符
int n = s.size();
for (int i = 0; i < n; ++i) {
if (!position.count(s[i])) {
// 字符首次出现,记录其索引并加入队列
position[s[i]] = i;
q.emplace(s[i], i);
}
else {
// 字符重复出现,标记为-1
position[s[i]] = -1;
// 从队列头部移除所有重复字符
while (!q.empty() && position[q.front().first] == -1) {
q.pop();
}
}
}
// 队列头部元素即为第一个不重复字符的索引,若队列为空则返回-1
return q.empty() ? -1 : q.front().second;
}
};
小tips:
在 C++ 中,emplace 是容器(如 vector、queue、map 等)提供的一种插入元素的方式,其作用类似于 push 或 insert,但效率更高。
emplace 的核心优势在于它直接在容器内部构造对象,而不需要先创建临时对象再复制 / 移动到容器中。这避免了额外的拷贝或移动操作,尤其适用于构造函数复杂或参数较多的对象。
对简单类型(如 int、char),emplace 和 push 的性能几乎相同。