华为 OD 训练营 · 题解精讲
LC387. 字符串中的第一个唯一字符
LC387. 字符串中的第一个唯一字符 视频地址。
题目描述
给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。 示例 1: 输入: s = "leetcode" 输出: 0
示例 2: 输入: s = "loveleetcode" 输出: 2
示例 3: 输入: s = "aabb" 输出: -1 提示: 1 <= s.length <= 10^5 s 只包含小写字母
题目解析
解题思路
本题要求找到字符串中第一个不重复字符的索引。核心思路是先统计每个字符的出现次数,再遍历字符串找到第一个出现次数为1的字符。
用到的数据结构是哈希表(Python 的 Counter 本质是字典),用于存储字符到频率的映射。算法分为两步: 1. 一次遍历统计频率(Counter(s) 内部实现为 O(n) 的哈希表计数)。 2. 第二次遍历字符串,按原顺序检查每个字符的频率,遇到频率为1的立即返回索引。
关键步骤
1. 统计频率:cnt = Counter(s),例如 s = "leetcode",得到 {'l':1, 'e':3, 't':1, 'c':1, 'o':1, 'd':1}。 2. 顺序查找:使用 enumerate(s) 同时获取索引 i 和字符 v,检查 cnt[v] == 1。
- 例如
"loveleetcode",遍历到索引2的'v'时频率为1,立即返回2。
3. 未找到返回 -1:若遍历结束无满足条件的字符,返回 -1。
ASCII 示意图(以 "leetcode" 为例):
索引: 0 1 2 3 4 5 6 7
字符: l e e t c o d e
频率: 1 3 3 1 1 1 1 3
↑ 第一个频率为1的字符,返回0复杂度分析
- 时间复杂度:O(n),其中 n 为字符串长度。两次线性遍历(计数和查找),每次操作均为 O(1) 的哈希表访问。
- 空间复杂度:O(1)。虽然使用了哈希表,但字符集固定为26个小写字母,因此空间为常数级。
参考代码
# 本题涉及到 Python 的一些语法知识
# Python常用内置函数、方法、技巧汇总
# https://og7kl7g6h8.feishu.cn/docx/AbbMdd4YHoGeQRxRGKJcJZs6nDb
class Solution:
def firstUniqChar(self, s: str) -> int:
# Counter 可以直接统计字符串、列表等可迭代对象的元素频率
# s = "leetcode"
# cnt = Counter({'e': 3, 'l': 1, 't': 1, 'c': 1, 'o': 1, 'd': 1})
cnt = Counter(s)
print(cnt)
# 如果想在for循环中同时获得列表的索引 i 和元素值 v
# 可以使用枚举内置函数 enumerate()
for i, v in enumerate(s):
# 如果找到了某个字符出现的频率为 1
if cnt[v] == 1:
# 返回它的下标即可
return i
# 如果不存在,则返回 -1
return -1