一.题目
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
案例:
s = "leetcode"
返回 0.
s = "loveleetcode",
返回 2.
注意事项:您可以假定该字符串只包含小写字母。
二.思路及代码
暴力枚举;(时间会炸)
class Solution:
def firstUniqChar(self, s):
"""
:type s: str
:rtype: int
"""
i = 0
j = 0
while i < len(s):
while j < len(s):
if s[i] != s[j] or i == j:
j += 1
else:
break
if j == len(s):
return i
else:
j = 0
i += 1
return -1
hash table:以单个字母的string为key,出现次数为value构建一个字典(hash table),然后再从头开始遍历给定的string,根据构建好的hash table判断,如果string里的这个项在hash table里的值为1,那么返回它的index,如果全部循环结束程序还没终止,那就证明没有合适的项,return -1。
class Solution:
def firstUniqChar(self, s):
"""
:type s: str
:rtype: int
"""
hash_table = {}
for i in s:
if i not in hash_table:
hash_table[i] = 1
else:
hash_table[i] += 1
for j in range(len(s)):
if hash_table[s[j]] == 1:
return j
return -1
利用字符串方法的str.find()和str.rfind()来判断是否有重复字符。
class Solution:
def firstUniqChar(self, s):
"""
:type s: str
:rtype: int
"""
s_set = set(s)
indx_list=[]
for i in s_set:
first_indx = s.find(i)
last_indx = s.rfind(i)
if first_indx == last_indx:
indx_list.append(first_indx)
if indx_list == []:
return -1
else:
return min(indx_list)
利用数组:因为这个字符串里的元素只能从26个字母里选,所以,我们可以将26个字母的小写形式构成一个字符串,然后循环这个字符串,计算每个字母在给定的s里出现的次数,并将出现次数为1的字母的index存起来,最后返回最小的index。
min(iterable) return value
class Solution:
def firstUniqChar(self, s):
"""
:type s: str
:rtype: int
"""
# c = [i for i in range(len(s)) if s.count(s[i]) == 1]
# if c != []:
# return min(c)
# else:
# return -1
temp = 'abcdefghijklmnopqrstuvwxyz'
c = [s.index(i) for i in temp if s.count(i) == 1]
return min(c or [-1])
注释里的方法和show出来的方法思路是一样的,那为什么用26个小写字母的循环,而不用注释里循环s的办法呢?
这个要考虑时间和空间复杂度的问题,如果s很小那么上面的方法ok,而如果s特别大会超时报错。而第二种方法固定循环26次,还是很小的。