返回

LeetCode 387:字符串中的第一个唯一字符——精妙算法助你找出字符串中的不重复字符

前端

LeetCode 387:“字符串中的第一个唯一字符”是一道经典的算法问题,它考验着我们的编程能力和算法思维。在这篇文章中,我们将介绍两种解决该问题的有效算法,帮助你快速找出字符串中的第一个不重复字符。

### 算法一:哈希表(字典)法

哈希表(字典)法是一种常见的字符串查找算法,它利用哈希表(字典)的数据结构来存储字符串中的字符及其出现次数。具体步骤如下:

1. 初始化一个哈希表(字典),将所有字符及其出现次数都初始化为 0。
2. 遍历字符串,将每个字符及其出现次数更新到哈希表(字典)中。
3. 遍历哈希表(字典),找到第一个出现次数为 1 的字符,并返回它的索引。

python
def first_unique_char_hash(s):
"""
哈希表法查找字符串中的第一个唯一字符

参数:
    s: 输入字符串

返回:
    第一个唯一字符的索引,如果不存在则返回 -1
"""
hash_table = {}  # 初始化哈希表
for char in s:  # 遍历字符串
    if char in hash_table:  # 如果字符已存在
        hash_table[char] += 1  # 出现次数加 1
    else:  # 如果字符不存在
        hash_table[char] = 1  # 初始化出现次数为 1
for index, char in enumerate(s):  # 遍历字符串
    if hash_table[char] == 1:  # 如果出现次数为 1
        return index  # 返回索引
return -1  # 如果不存在唯一字符,返回 -1

print(first_unique_char_hash("leetcode")) # 0
print(first_unique_char_hash("loveleetcode")) # 2
print(first_unique_char_hash("aabb")) # -1


### 算法二:滑动窗口法

滑动窗口法是一种高效的字符串查找算法,它利用滑动窗口来查找字符串中的子串。具体步骤如下:

1. 初始化一个滑动窗口,窗口大小为 1。
2. 将窗口移动到字符串的开头,并检查窗口内的字符是否唯一。
3. 如果窗口内的字符唯一,则返回窗口的起始位置。
4. 否则,将窗口向右移动一个字符,并重复步骤 2 和 3。

python
def first_unique_char_sliding_window(s):
"""
滑动窗口法查找字符串中的第一个唯一字符

参数:
    s: 输入字符串

返回:
    第一个唯一字符的索引,如果不存在则返回 -1
"""
left, right = 0, 0  # 滑动窗口的左右边界
char_set = set()  # 存储窗口内已出现的字符
while right < len(s):  # 循环移动窗口
    if s[right] not in char_set:  # 如果字符未出现过
        char_set.add(s[right])  # 将字符添加到集合中
        left = right  # 更新窗口的左边界
    else:  # 如果字符已出现过
        char_set.remove(s[left])  # 从集合中移除左边界处的字符
        left += 1  # 更新窗口的左边界
    right += 1  # 更新窗口的右边界
    if len(char_set) == 1:  # 如果集合中只包含一个字符
        return left  # 返回窗口的左边界
return -1  # 如果不存在唯一字符,返回 -1

print(first_unique_char_sliding_window("leetcode")) # 0
print(first_unique_char_sliding_window("loveleetcode")) # 2
print(first_unique_char_sliding_window("aabb")) # -1


这两种算法都可以在 O(n) 的时间复杂度内找到字符串中的第一个唯一字符,其中 n 为字符串的长度。哈希表法利用哈希表来存储字符及其出现次数,因此在查找时只需要直接查找哈希表即可。滑动窗口法利用滑动窗口来查找字符串中的子串,在移动窗口时只需要检查窗口内的字符是否唯一即可。

希望这篇文章对你有帮助,祝你刷题愉快!