题目描述
在给定的字符串 s
中,找到第一个不重复的字符并返回其索引。如果字符串中所有字符都是重复的,则返回 -1
。
例如:
- 对于输入
s = "leetcode"
,期望输出为0
,因为'l'
是第一个不重复的字符。 - 对于输入
s = "loveleetcode"
,期望输出为2
,因为'v'
是第一个不重复的字符。 - 对于输入
s = "aabb"
,期望输出为-1
,因为所有字符都是重复的。
解题思路
为了解决这个问题,我们可以使用哈希表来统计每个字符在字符串中出现的次数,并遍历字符串找到第一个出现次数为 1
的字符。
步骤:
-
使用哈希表统计频次:
- 创建一个
unordered_map<char, int>
来存储每个字符及其出现的频次。 - 遍历字符串
s
,对每个字符ch
,将其在哈希表中的计数加一。
- 创建一个
-
找到第一个不重复的字符:
- 再次遍历字符串
s
,对于每个字符s[i]
,检查其在哈希表中的计数。 - 如果找到某个字符的计数为
1
,则返回其索引i
,因为它是第一个不重复的字符。
- 再次遍历字符串
-
处理所有字符都重复的情况:
- 如果遍历完字符串后都没有找到出现次数为
1
的字符,则返回-1
。
- 如果遍历完字符串后都没有找到出现次数为
复杂度分析:
- 时间复杂度:O(n),其中 n 是字符串的长度。我们需要遍历字符串两次:一次用于统计字符频次,另一次用于找到第一个不重复的字符。
- 空间复杂度:O(1),因为哈希表存储的键值对最多是字符集的大小(在这里是小写字母,即 26 个),空间复杂度是常数级别的。
完整代码
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
class Solution {
public:
int firstUniqChar(string s) {
unordered_map<char, int> frequency;
// 第一步:统计每个字符的频次
for (char ch : s) {
++frequency[ch];
}
// 第二步:找到第一个不重复的字符的索引
for (int i = 0; i < s.size(); ++i) {
if (frequency[s[i]] == 1) {
return i;
}
}
// 如果所有字符都是重复的,则返回 -1
return -1;
}
};
int main() {
Solution sol;
// 测试示例
cout << sol.firstUniqChar("leetcode") << endl; // 输出 0
cout << sol.firstUniqChar("loveleetcode") << endl; // 输出 2
cout << sol.firstUniqChar("aabb") << endl; // 输出 -1
return 0;
}
博客结构建议
-
题目描述:
- 简要描述问题的背景和要求,例如如何在给定字符串中找到第一个不重复的字符。
-
解题思路:
- 分步解释使用哈希表的方法来解决问题,包括统计字符频次和找到第一个不重复字符的过程。
-
代码实现:
- 给出完整的 C++ 代码实现,包括类定义、函数定义和
main
函数。
- 给出完整的 C++ 代码实现,包括类定义、函数定义和
-
示例运行:
- 给出几个测试用例,并展示代码运行后的输出结果,与题目中的示例进行对比。
-
复杂度分析:
- 讨论算法的时间复杂度和空间复杂度,分析代码的性能和适用场景。
-
总结:
- 总结本文讨论的内容,强调使用哈希表解决问题的有效性和实用性。
通过以上结构,你可以清晰地展示解题思路和代码实现,使读者能够理解和运用这种方法解决类似的字符串处理问题。