1. 程式人生 > 其它 >leetcode-387:字串中的第一個唯一字元(佇列以及堆疊最簡單的實現方式)

leetcode-387:字串中的第一個唯一字元(佇列以及堆疊最簡單的實現方式)

技術標籤:演算法從零開始python佇列pythonleetcode演算法字串

LC 字串中的第一個唯一字元

題目:

題目連結
給定一個字串,找到它的第一個不重複的字元,並返回它的索引。如果不存在,則返回 -1。
示例:

s = "leetcode"
返回 0

s = "loveleetcode"
返回 2

提示:你可以假定該字串只包含小寫字母。

解題:

方法一:使用雜湊表儲存頻數

使用了計數器Counter

class Solution:
    def firstUniqChar
(self, s: str) -> int: frequency = collections.Counter(s)#字串也是可以直接用Conter計數的 for i, ch in enumerate(s): if frequency[ch] == 1: return i return -1

在這裡插入圖片描述
說明:
字典中,先被放入的鍵在前面,即使後續被修改依舊在前面。
Conter是按鍵對應值大小,從大到小的排,如果值一樣大, 則按照放入順序。所以上面直接
frequency[ch] == 1就可以找到第一個

唯一字元

方法二:使用雜湊表儲存索引

class Solution:
    def firstUniqChar(self, s: str) -> int:
        position = dict()
        n = len(s)
        for i, ch in enumerate(s):
            if ch in position:
                position[ch] = -1 #如果第二次遇到,就變成-1,因此只有出現一次的值為索引i
            else:
                position[
ch] = i first = n for pos in position.values(): if pos != -1 and pos < first: first = pos if first == n: first = -1 return first

在這裡插入圖片描述

方法三:佇列

雜湊表中存的都是第一次遇到字元的索引(用來判斷是否只遇到過1次,如果多次的話,在佇列中會順序pop,直到遇到第一個只出現一次的字元),佇列中存的是每次的字元和索引,

class Solution:
    def firstUniqChar(self, s: str) -> int:
        position = dict()
        q = collections.deque()#只是一種雙向佇列,這邊起到佇列的作用
        n = len(s)
        for i, ch in enumerate(s):
            if ch not in position:
                position[ch] = i
                q.append((s[i], i))
            else:
                position[ch] = -1
                while q and position[q[0][0]] == -1:
                    q.popleft()
        return -1 if not q else q[0][1]

佇列:
有很多種,最簡單的實現方式

queue = list()
queue.append("a")
queue.pop(0)

(上述方法三的程式碼完全可以用這種方式)
當然python標準庫中包含了四種佇列,分別是queue.Queue / asyncio.Queue / multiprocessing.Queue / collections.deque

堆疊:
最簡單的實現方式

stack = list()
stack.append("a")
stack.pop()