一、题目
题目链接:力扣
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
示例 1:
输入:s = "abaccdeff"
输出:'b'
示例 2:
输入:s = ""
输出:' '
限制:
0 <= s 的长度 <= 50000
二、题解
1、思路
👹 无序哈希表
最好不要用unordered_map<char, int> unmap,理由见map<string, int>中的 int 的初始值为什么是 0? - 知乎,因为unmap[a] = ?,不明确!
第一次遍历填充哈希表,第二次遍历查找哈希表。注意如果不存在只出现一次的数组,需要返回空格。这样可以保证我们得到的是第一个只出现一次的字符!
👹 有序哈希表
哈希表是 去重 的,即哈希表中键值对数量 ≤ 字符串 s 的长度。因此,相比于无序哈希表,有序哈希表可以减少了第二轮遍历的循环次数。当字符串很长(重复字符很多)时,方法二则效率更高。
如何保证找到第一个出现一次的呢?出现一次使用哈希表搞定,第一个呢?采用数组存储字符出现的顺序,该数组只存储字符第一次出现的一个,后面直接遍历该数组即可。
👹 队列
选取第一个只出现一次的字符,可以利用队列先进先出的性质完成。
哈希表标记数组是否出现过,第一次出现标记为false,多次出现标记为true;第一次出现的字符标记为false的同时放到队列中,在哈希表标记为true的时候,判断队列头部元素是否是重复出现的元素,如果是则循环弹出,直至头部不是重复出现的元素。注意,只关心头部元素,因为我们只要第一个出现一次的字符!(延迟删除)
注意:
代码中不能使用if,需要使用while,不然无法正确删除队列头部重复元素!
2、代码实现
👹 无序哈希表
class Solution {
public:
char firstUniqChar(string s) {
if(s == " ")return ' ';
unordered_map<char, bool> unmap;
for(auto& ch : s)
{
unmap[ch] = (unmap.find(ch) == unmap.end());// 出现第一次时未找到,为false,出现第二次找到第一次的,为true
}
for(auto& ch : s)
{
if(unmap[ch] == true)return ch;
}
return ' ';
}
};
👹 有序哈希表
class Solution {
public:
char firstUniqChar(string s) {
if(s == " ")return ' ';
unordered_map<char, bool> unmap;
vector<char> keys;
for(auto& ch : s)
{
if(unmap.count(ch) == 0)keys.emplace_back(ch);// 记录第一次出现的字符(也就是按出现顺序记录)
unmap[ch] = (unmap.find(ch) == unmap.end());// 出现第一次时未找到,为false,出现第二次找到第一次的,为true
}
for(auto& ch : keys)
{
if(unmap[ch] == true)return ch;// 返回只出现一次的字符
}
return ' ';
}
};
👹 队列
哈希表用来判断是否重复,队列只是用来保证选择第一个不重复的!
class Solution {
public:
char firstUniqChar(string s) {
if(s == " ")return ' ';
unordered_map<char, bool> unmap;
queue<char> que;
for(auto& ch : s)
{
// 字符从未出现过(首次出现)
if(unmap.find(ch) == unmap.end())
{
que.emplace(ch);
unmap[ch] = false;// 第一次出现值为false
}
else// 如果已经出现过
{
unmap[ch] = true;// 已经出现过值为true
// 一定要是while,不能是if,不然可能删除一次后不进入,或者使用if直接放在else外部
while(!que.empty() && unmap[que.front()] == true )que.pop();
}
}
return que.empty() ? ' ' : que.front();
}
};
3、复杂度分析
👹 无序哈希表
时间复杂度:O(n);
空间复杂度:O(1)。// 一定要注意,不是O(n),因为小写字母只有26个!
👹 有序哈希表
时间复杂度:O(n);
空间复杂度:O(1)。
👹 队列
时间复杂度:O(n);
空间复杂度:O(1)。
4、运行结果
👹 无序哈希表
👹 有序哈希表
👹 队列
2023/02/11 22:51于光电信息大楼