字符串中的第一个唯一字符
概述:给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。
输入: s = "leetcode"
输出: 0
输入: s = "loveleetcode"
输出: 2
输入: s = "aabb"
输出: -1
方法一:暴力循环
思路:直接对剔除 i 的新数组判断,若不重复,直接返回即可。
# 暴力循环
# 直接对剔除 i 的新数组判断,若不重复,直接返回即可。
class Solution:
def firstUniqChar(self, s: str) -> int:
n = len(s)
for i in range(n):
if s[i] not in (s[:i] + s[i + 1:]):
return i
return -1
方法二:Counter() 方法
思路:用 Counter() 方法统计出现次数,再依次循环判断是否重复即可。
# Counter() 方法
# 用 Counter() 方法统计出现次数,再依次循环判断是否重复即可。
class Solution:
def firstUniqChar(self, s: str) -> int:
s_dict = collections.Counter(s)
for i, v in enumerate(s):
if s_dict[v] == 1:
return i
return -1
方法三:字典
思路:首先手写一个出现次数的字典,然后再对不重复的元素进行判断即可。
# 字典
# 首先手写一个出现次数的字典,然后再对不重复的元素进行判断即可。
class Solution:
def firstUniqChar(self, s: str) -> int:
s_dict = {}
n = len(s)
for i, v in enumerate(s):
if v in s_dict:
s_dict[v] = -1
else:
s_dict[v] = i
ans = n
for value in s_dict.values():
if value != -1 and value < ans:
ans = value
if ans == n:
return -1
return ans
方法四:字典+队列
思路:依旧用字典作为存储,不同在于借助了队列 FIFO 的特点,把重复的元素标记为 -1,依次循环判断即可。
# 字典+队列
# 依旧用字典作为存储,不同在于借助了队列 FIFO 的特点,
# 把重复的元素标记为 -1,依次循环判断即可。
class Solution:
def firstUniqChar(self, s: str) -> int:
s_dict = {}
s_q = collections.deque()
n = len(s)
for i, v in enumerate(s):
if v not in s_dict:
s_dict[v] = i
s_q.append((v, i))
else:
s_dict[v] = -1
while s_q and s_dict[s_q[0][0]] == -1:
s_q.popleft()
return -1 if not s_q else s_q[0][1]
总结
索然无味,赶紧准备面试去了