劍指offer_50_第一個只出現一次的字元
阿新 • • 發佈:2020-07-31
第一個只出現一次的字元
題目連結:https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/
題目內容:
在字串 s 中找出第一個只出現一次的字元。如果沒有,返回一個單空格。 s 只包含小寫字母。
示例:
s = "abaccdeff"
返回 "b"
s = ""
返回 " "
限制:
0 <= s 的長度 <= 50000
題目解析
題目解析內容來自於題解中 Krahets
這題題意簡單明瞭。立刻就能想到雜湊表來統計,遍歷。對應 python 中的字典
但是在如何使用字典這件事中仍然大有可為。
方法一:雜湊表
- 遍歷字元
s
,使用字典統計"各字元數量是否 > 1"。 - 再遍歷字串
s
,在字典中找到首個"數量為 1 的字元",並返回
演算法流程:
-
初始化:生成一個空字典。記為
dic
; -
字元統計:遍歷字串
s
中每一個字元c
;- 若
dict
中 不包含 鍵(key)c
:則向dic
中新增鍵值對(c, true)
,代表字元c
的數量為 1; - 若
dict
中 包含 鍵(key)c
:則修改dic
鍵c
的值為false
,代表字元c
的數量 > 1;
- 若
-
查詢數量為1的字元
s
中每個字元c
; 若dic
中鍵c
對應的值為True
,則返回c
。 -
返回
" "
, 代表字串無數量為 1 的字元
複雜度分析:
- 時間複雜度O(N): N 為字串
s
的長度;序遍歷s
兩輪,使用 O(N); 字典查詢的時間複雜度為 O(1) - 空間複雜度O(N): 字典需儲存 N 個字元的鍵值對,使用 O(N) 大小的額外空間
程式碼
Python 程式碼中
not c in dic
整體為一個布林值,c in dic
為判斷字典中是否含有鍵c
。
class Solution: def firstUniqChar(self, s: str) -> str: dic = {} for c in s: dic[c] = not c in dic for c in s: if dic[c]: return c return " "
方法二:有序雜湊表
在雜湊表的基礎上,有序雜湊表中的鍵值對是 按照插入順序排序 的。基於此,可通過遍歷有序雜湊表,實現搜尋首個 “數量為 1 的字元”。
雜湊表是 去重 的,即雜湊表中鍵值對數量 \leq≤ 字串 s
的長度。因此,相比於方法一,方法二減少了第二輪遍歷的迴圈次數。當字串很長(重複字元很多)時,方法二則效率更高。
複雜度分析:
時間和空間複雜度均與 “方法一” 相同,而具體分析時間複雜度:
- 方法一 O(2N) : N 為字串 s 的長度;需遍歷 s 兩輪;
- 方法二 O(N):遍歷 s 一輪,遍歷 dic 一輪。
程式碼
python3.6 之後,預設字典就是有序的。詳情可見為什麼Python 3.6以後字典有序並且效率更高?
class Solution:
def firstUniqChar(self, s: str) -> str:
dic = {}
for c in s:
dic[c] = not c in dic
for k, v in dic.items():
if v: return k
return " "