题目
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
示例:
s = "abaccdeff"
返回 "b"s = ""
返回 " "限制:
0 <= s 的长度 <= 50000
思路
本题显然要使用hash表,在python中即为字典;
思路1 无序哈希表
字典创建步骤:
首先,创建字典dic;
之后,遍历字符串,对每一个字符c:
- 如果该字符在dic中,则将该字符对应的value设为false; false表示出现了不止一次。
- 否则(即不在dic中),则在字典中加入键值对{c, true}.
接下来是 第一个字符搜索步骤
遍历字符串,直到第一个在字典中键值为true的字符为止,返回该字符。
思路2 有序哈希表
将上述字典创建步骤中的字典改为有序字典;
这样,在搜索时只需对字典dic进行遍历,返回第一个值为ture的key即可。
显然,当字符串很长、有很多重复字符时,有序哈希表很有用。
代码
无序哈希表的代码如下:
class Solution:
def firstUniqChar(self, s: str) -> str:
dic = {}
for char in s:
if char in dic.keys():
dic[char] = False # 第二次出现
else:
dic[char] = True # 第一次出现
for char in s:
if dic[char]:
return char
return " "
有序哈希表的代码如下:
class Solution:
def firstUniqChar(self, s: str) -> str:
dic = collections.OrderedDict()
for char in s:
if char in dic.keys():
dic[char] = False # 第二次出现
else:
dic[char] = True # 第一次出现
for key in dic:
if dic[key]:
return key
return " "
值得注意的是,自Python3.6开始,改写了 dict 的内部算法,Python3.6 版本以后的 dict 是有序的,所以也就无须再关注 dict 顺序性的问题。即python3.6之后的代码完全可以改为:
class Solution:
def firstUniqChar(self, s: str) -> str:
dic = {}
for char in s:
if char in dic.keys():
dic[char] = False # 第二次出现
else:
dic[char] = True # 第一次出现
for key in dic:
if dic[key]:
return key
return " "
复杂度分析
时间复杂度: 因为规定了s中只有小写字母,所以dic.keys()的大小为有限的不大于26的常数,故时间复杂度为O(N);
空间复杂度: O(N)
总结
python中的哈希表实现简单