题目描述
思路解析动画文字版
记住两趟的分工:第一趟只管「数清楚每个字母出现几次」,第二趟只管「按原顺序找第一个出现 1 次的」。下面每一帧都在套这两趟。
第一趟:从头扫一遍,把每个字符出现的次数都记进右边的计数表 cnt。现在 cnt 是空的。
第一趟扫到下标 0,这一格是 'a'(橙色高亮)。先看清是哪个字符,下一步把它的次数加一。
把 'a' 的次数加一,它现在出现了 1 次。第一趟走完,cnt 就记下了每个字母各出现几次。
第一趟扫到下标 1,这一格是 'a'(橙色高亮)。先看清是哪个字符,下一步把它的次数加一。
把 'a' 的次数加一,它现在出现了 2 次。第一趟走完,cnt 就记下了每个字母各出现几次。
第一趟扫到下标 2,这一格是 'b'(橙色高亮)。先看清是哪个字符,下一步把它的次数加一。
把 'b' 的次数加一,它现在出现了 1 次。第一趟走完,cnt 就记下了每个字母各出现几次。
第一趟扫到下标 3,这一格是 'b'(橙色高亮)。先看清是哪个字符,下一步把它的次数加一。
把 'b' 的次数加一,它现在出现了 2 次。第一趟走完,cnt 就记下了每个字母各出现几次。
第一趟扫到下标 4,这一格是 'c'(橙色高亮)。先看清是哪个字符,下一步把它的次数加一。
把 'c' 的次数加一,它现在出现了 1 次。第一趟走完,cnt 就记下了每个字母各出现几次。
第一趟扫到下标 5,这一格是 'd'(橙色高亮)。先看清是哪个字符,下一步把它的次数加一。
把 'd' 的次数加一,它现在出现了 1 次。第一趟走完,cnt 就记下了每个字母各出现几次。
第一趟扫到下标 6,这一格是 'e'(橙色高亮)。先看清是哪个字符,下一步把它的次数加一。
把 'e' 的次数加一,它现在出现了 1 次。第一趟走完,cnt 就记下了每个字母各出现几次。
第一趟结束。计数表已经数清:a 和 b 各出现 2 次,c、d、e 各出现 1 次。接下来第二趟按原顺序找第一个次数为 1 的字符。
第二趟扫到下标 0 的 'a',查计数表它出现了 2 次,不止一次(标红),不是答案,继续往右看。
第二趟扫到下标 1 的 'a',查计数表它出现了 2 次,不止一次(标红),不是答案,继续往右看。
第二趟扫到下标 2 的 'b',查计数表它出现了 2 次,不止一次(标红),不是答案,继续往右看。
第二趟扫到下标 3 的 'b',查计数表它出现了 2 次,不止一次(标红),不是答案,继续往右看。
第二趟扫到下标 4 的 'c',去计数表一查,它的次数是 1——这就是第一个只出现一次的字符。停下来,答案就是下标 4。
整道题做完:第一个只出现一次的字符是 'c',它的下标是 4,返回 4。
三个高频追问:O(1) 空间的由来、能否一趟、以及返回字符的变体。
参考代码
def firstUniqChar(s): from collections import Counter cnt = Counter(s) # 第一趟:数清每个字符出现几次 for i, ch in enumerate(s): # 第二趟:按原顺序找 if cnt[ch] == 1: # 第一个只出现一次的 return i return -1 # 没有则返回 -1复杂度
- 时间:O(n),两趟都只把字符串扫一遍,n 是字符串长度
- 空间:O(1),计数表最多 26 个小写字母,大小固定,与 n 无关
易错点
面试追问把动画讲成自己的话
追问为什么空间是 O(1) 而不是 O(n)?
追问能不能只扫一趟就解决?
追问如果要返回的是字符本身而不是下标呢?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
字符串相加
LeetCode 415 · 简单 · 沿着 字符串套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题