查找第一个不重复的字符

57 阅读1分钟

本题目对应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官方,我在上面加了部分注释:

链接:leetcode.cn/problems/fi…

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 是容器(如 vectorqueuemap 等)提供的一种插入元素的方式,其作用类似于 push 或 insert,但效率更高

emplace 的核心优势在于它直接在容器内部构造对象,而不需要先创建临时对象再复制 / 移动到容器中。这避免了额外的拷贝或移动操作,尤其适用于构造函数复杂或参数较多的对象。

对简单类型(如 intcharemplace 和 push 的性能几乎相同。