leetcode387—字符串中的第一个唯一字符
题目:
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
示例1:
s = “leetcode”
返回 0
示例2:
s = “loveleetcode”
返回 2
提示:你可以假定该字符串只包含小写字母。
解法:
字符串是可迭代对象,可以进行类似for循环的迭代操作。
从列表中删除元素:
- 删除指定值的元素:
list.remove(d)
删除了值为d的元素。 - 删除指定索引的元素:
list.pop(d)
删除并返回索引为d的元素,即第d+1个元素,pop函数不指定索引,会默认返回最后一个元素。del list[d]
删除索引为d的元素,del[start:end]
可以删除指定区间的元素(根据python的规则删除到索引end的前一位元素)。
- 清空整个列表:
list.clear()
。
1. 两次遍历法
第一次遍历,利用哈希表统计所有字符出现的个数。
第二次遍历,找到第一个出现个数为1的元素,返回索引。
代码如下:
class Solution:
def firstUniqChar(self, s: str) -> int:
n = len(s)
m = collections.Counter()
for i in s:
m[i] += 1
for j in range(n):
if m[s[j]] == 1:
return j
return -1
复杂度分析:
- 时间复杂度: O ( n ) O(n) O(n),遍历两次字符串,n为字符串长度。
- 空间复杂度: O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣), ∣ Σ ∣ |\Sigma| ∣Σ∣为字符集,即多少种字符,根据字符种数生成了哈希表。
2.列表+哈希表法
- 遍历字符串,若不在哈希表中则值作为键,索引作为值加入哈希表,字符加入列表。
- 如果在哈希表中存在,则判断是否在列表中,在的话从列表删除,不在的话不进行操作。(处理同一个字符出现奇数次的情况)
- 判断列表是否为空,空则返回-1,否则找到列表第一个元素在哈希表中的位置,返回其索引。(因为重复出现的元素会被列表删除,所以留下来的是非重复的,并且是有序的,符合字符串中出现的顺序)。
代码如下:
class Solution:
def firstUniqChar(self, s: str) -> int:
hashmap = {}
list1 = []
for i,d in enumerate(s):
if d in hashmap.keys():
if d in list1:
list1.remove(d)
else:
hashmap[d] = i
list1.append(d)
if len(list1)>0:
first = list1[0]
return hashmap[first]
return -1
复杂度分析:
- 时间复杂度: O ( n ) O(n) O(n),遍历了一次字符串, n为字符串长度。
- 空间复杂度: O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣), ∣ Σ ∣ |\Sigma| ∣Σ∣为字符集,即多少种字符,根据字符种数生成了哈希表和列表。
总结
字符串可迭代的知识和列表删除操作的代码重新复习了一下。
第一种方法参考了题解,思路很简洁,值得学习。