034 · First Unique Character in a String

algorithm
Published

June 10, 2026

My First Thoughts

这道题要返回不重复的字符。既然要知道一个字符是不是“不重复”,那无论如何都得看过字符串里的字符。

第一反应是:Python 里会不会有类似 unique 或者 duplicate 的函数,可以直接判断一个字符是不是不重复?但从算法题角度看,还是要自己把这个过程写出来。

最直接的思路是先用字典计数:

def uniChar(s):
    counts = {}

    for char in s:
        counts[char] = counts.get(char, 0) + 1

    for key, value in counts.items():
        if value == 1:
            return key

    return -1

这个方向是自然的:counts 记录每个字符出现几次,后面看到哪个字符的次数是 1,就说明它是不重复字符。

比如:

s = "leetcode"

计数之后,"l" 的次数是 1,所以第一眼会觉得返回 "l" 就可以了。


Why That Is Not Enough

上面的计数思路是对的,真正需要纠正的是返回值。

题目问的是:

返回第一个不重复字符的下标。

不是返回字符本身。

所以如果 s = "leetcode",答案不是:

"l"

而是:

0

也就是说,字典 counts 负责告诉我们“这个字符出现了几次”,但最终答案还要回到原字符串 s 里,按从左到右的顺序找到第一个 counts[char] == 1 的位置。


Final Idea

关键思路是:

第一遍用字典统计每个字符出现次数;第二遍按原字符串顺序找第一个次数为 1 的字符,并返回它的下标。

从原来的写法开始:

for key, value in counts.items():
    if value == 1:
        return key

这里返回的是字符。要改成返回下标,就不要遍历 counts.items(),而是遍历原字符串:

for index, char in enumerate(s):
    if counts[char] == 1:
        return index

enumerate(s) 会同时给出当前位置 index 和当前字符 char。这样既能用 counts[char] 判断它是不是不重复,也能在找到答案时直接返回下标。


Why It Works

第一遍遍历结束后,counts 里保存了每个字符在整个字符串中出现的次数。

第二遍重新从左到右遍历 s。对于当前字符 char

  • 如果 counts[char] == 1,说明它在整个字符串中只出现一次
  • 因为我们是从左到右遍历,所以第一个满足这个条件的字符,就是题目要的第一个不重复字符

如果第二遍走完都没有找到次数为 1 的字符,说明每个字符都重复了,返回 -1


Code

def firstUniqChar(s):
    counts = {}

    for char in s:
        counts[char] = counts.get(char, 0) + 1

    for index, char in enumerate(s):
        if counts[char] == 1:
            return index

    return -1

Complexity

Time \(O(n)\) - ns 的长度;第一遍计数,第二遍找第一个不重复字符
Space \(O(n)\) - 字典里最多保存 s 中出现过的不同字符

Takeaway

计数字典可以回答“每个字符出现了几次”,但题目如果要返回下标,最后通常还要回到原字符串里按顺序遍历。这样既保留了计数信息,也能拿到正确的位置。


Quiz