Stack與Queue

Stack

image.png

由于堆棧數(shù)據(jù)結(jié)構(gòu)只允許在一端進(jìn)行操作,因而按照后進(jìn)先出(LIFO, Last In First Out)的原理運(yùn)作噩斟。實(shí)現(xiàn)方式主要有順序棧和鏈棧

基本操作:
  init: -> Stack
  push: N x Stack -> Stack
  top: Stack -> (N U ERROR)
  pop: Stack -> Stack
  isempty: Stack -> Boolean
一、先看LeetCode 155. Min Stack
  • 順序棧孤个, 使用python的list實(shí)現(xiàn)
class MinStack(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.data = []

    def push(self, x):
        """
        :type x: int
        :rtype: void
        """
        self.data.append(x)

    def pop(self):
        """
        :rtype: void
        """
        if self.data:
            self.data.pop(-1)
        
    def top(self):
        """
        :rtype: int
        """
        if self.data:
            return self.data[-1]
        
    def getMin(self):
        """
        :rtype: int
        """
        if self.data:
            return min(self.data)
  • 鏈棧剃允,由于棧操作只在一斷操作,可以用單鏈表采用頭插法實(shí)現(xiàn)
class Node(object):
    def __init__(self, x):
        self.val = x
        self.next = None
        self.pre = None


class MinStack(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.head = Node(None)

    def push(self, x):
        """
        :type x: int
        :rtype: void
        """
        node = Node(x)
        if self.head.next:
            node.next = self.head.next
            self.head.next = node
        else:
            self.head.next = node

    def pop(self):
        """
        :rtype: void
        """
        if self.head.next:
            self.head.next = self.head.next.next
        
    def top(self):
        """
        :rtype: int
        """
        if self.head.next:
            return self.head.next.val
        
    def getMin(self):
        """
        :rtype: int
        """
        p = self.head.next
        min = float('inf')
        while p:
            if min > p.val:
                min = p.val
            p = p.next
        return min

可以看到getMin函數(shù)需要的時(shí)間復(fù)雜度是O(n)齐鲤,如果要降低getMin的時(shí)間復(fù)雜度斥废,可以每個(gè)數(shù)據(jù)元存儲(chǔ)當(dāng)前值加當(dāng)前最小值,需要空間復(fù)雜度O(n)

Queue

image.png

先進(jìn)先出(FIFO, First-In-First-Out)的線性表给郊。在具體應(yīng)用中通常用鏈表或者數(shù)組來(lái)實(shí)現(xiàn)牡肉。隊(duì)列只允許在后端(稱為rear)進(jìn)行插入操作,在前端(稱為front)進(jìn)行刪除操作丑罪。
那么如何用鏈表實(shí)現(xiàn)一個(gè)隊(duì)列呢荚板,首先隊(duì)列是雙端操作凤壁,涉及到出隊(duì)的時(shí)候需要?jiǎng)h除尾節(jié)點(diǎn)吩屹,如果用單鏈表的話每次刪除都是O(n)的操作跪另,所以用雙向鏈表實(shí)現(xiàn)煤搜,可以控制刪除操作為O(1)

class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None
        self.pre = None

class Queue(object):
    def __init__(self):
        self.tail = ListNode(None)
        self.head = ListNode(None)
        self.tail.next = self.head
        self.head.next = self.tail

    def enqueue(self, item):
        cur_node = ListNode(item)
        if self.head.next == self.tail:
            self.head.next = cur_node
            self.tail.next = cur_node
            cur_node.pre = self.head
            cur_node.next = self.tail
        else:
            pre_node = self.head.next
            self.head.next = cur_node
            pre_node.pre = cur_node
            cur_node.pre = self.head

    def dequeue(self):
        cur_node = self.tail.next
        pre_node = cur_node.pre
        if cur_node == self.head:
            return
        self.tail.next = pre_node
        pre_node.next = self.tail
        return cur_node.val

    def empty(self):
        return self.head.next == self.tail
二免绿、LeetCode 225. Implement Stack using Queues

用隊(duì)列實(shí)現(xiàn)棧,這里先用list實(shí)現(xiàn)一個(gè)隊(duì)列FIFO嘲驾,根據(jù)棧的特性FILO,
所以用兩個(gè)隊(duì)列,入棧的操作直接壓入有數(shù)據(jù)的隊(duì)列辽故,當(dāng)出棧是直接把有數(shù)據(jù)的隊(duì)列依次pop到另一個(gè)空隊(duì)列症见,當(dāng)剩下最后一個(gè)數(shù)據(jù)即棧頂元素

class Queue(object):
    def __init__(self):
        self.data = []
        
    def pop(self):
        if self.data:
            return self.data.pop(0)
    
    def push(self, x):
        self.data.append(x)
    
    def tail(self):
        if self.data:
            return self.data[-1]
    
    def empty(self):
        if self.data:
            return False
        return True


class MyStack(object):

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.queue_a = Queue()
        self.queue_b = Queue()
        
    def push(self, x):
        """
        Push element x onto stack.
        :type x: int
        :rtype: void
        """
        q = self.queue_b if self.queue_a.empty() else q = self.queue_a
        q.push(x)

    def pop(self):
        """
        Removes the element on top of the stack and returns that element.
        :rtype: int
        """
        if not self.queue_a.empty():
            sour_q = self.queue_a
            dest_q = self.queue_b
        else:
            dest_q = self.queue_a
            sour_q = self.queue_b
        while not sour_q.empty():
            data = sour_q.pop()
            if sour_q.empty():
                return data
            dest_q.push(data)
            
    def top(self):
        """
        Get the top element.
        :rtype: int
        """
        q = self.queue_b if self.queue_a.empty() else q = self.queue_a
        return q.tail()
        
    def empty(self):
        """
        Returns whether the stack is empty.
        :rtype: bool
        """
        return self.queue_a.empty() and self.queue_b.empty()
三、LeetCode 232. Implement Queue using Stacks

根據(jù)隊(duì)列FIFO和棧FILO的特性谋作,使用兩個(gè)棧的話遵蚜,一個(gè)棧專入數(shù)據(jù)stack_in帖池,一個(gè)棧專出數(shù)據(jù)stack_out,所有數(shù)據(jù)走stack_out出吭净,即實(shí)現(xiàn)隊(duì)列

class Stack(object):
    def __init__(self):
        self.data = []
    
    def push(self, x):
        self.data.append(x)
    
    def pop(self):
        if self.data:
            return self.data.pop(-1)
        
    def empty(self):
        if self.data:
            return False
        return True
    
    def buttom(self):
        if self.data:
            return self.data[0]

class MyQueue(object):

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.stack_in = Stack()
        self.stack_out = Stack()
        
    def push(self, x):
        """
        Push element x to the back of queue.
        :type x: int
        :rtype: void
        """
        self.stack_in.push(x)

    def pop(self):
        """
        Removes the element from in front of queue and returns that element.
        :rtype: int
        """
        if self.stack_out.empty():
            while not self.stack_in.empty():
                data = self.stack_in.pop()
                self.stack_out.push(data)
        return self.stack_out.pop()

    def peek(self):
        """
        Get the front element.
        :rtype: int
        """
        if self.stack_out.empty() and not self.stack_in.empty():
            return self.stack_in.data[0]
        else:
            return self.stack_out.data[-1]

    def empty(self):
        """
        Returns whether the queue is empty.
        :rtype: bool
        """
        return self.stack_in.empty() and self.stack_out.empty()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碘裕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子攒钳,更是在濱河造成了極大的恐慌帮孔,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件不撑,死亡現(xiàn)場(chǎng)離奇詭異文兢,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)焕檬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門姆坚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人实愚,你說(shuō)我怎么就攤上這事兼呵⊥酶ǎ” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵击喂,是天一觀的道長(zhǎng)维苔。 經(jīng)常有香客問(wèn)我,道長(zhǎng)懂昂,這世上最難降的妖魔是什么介时? 我笑而不...
    開(kāi)封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮凌彬,結(jié)果婚禮上沸柔,老公的妹妹穿的比我還像新娘。我一直安慰自己铲敛,他們只是感情好褐澎,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著伐蒋,像睡著了一般工三。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上咽弦,一...
    開(kāi)封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天徒蟆,我揣著相機(jī)與錄音,去河邊找鬼型型。 笑死段审,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的闹蒜。 我是一名探鬼主播寺枉,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼绷落!你這毒婦竟也來(lái)了姥闪?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤砌烁,失蹤者是張志新(化名)和其女友劉穎筐喳,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體函喉,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡避归,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了管呵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梳毙。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖捐下,靈堂內(nèi)的尸體忽然破棺而出账锹,到底是詐尸還是另有隱情萌业,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布奸柬,位于F島的核電站生年,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鸟缕。R本人自食惡果不足惜晶框,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一排抬、第九天 我趴在偏房一處隱蔽的房頂上張望懂从。 院中可真熱鬧,春花似錦蹲蒲、人聲如沸番甩。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)缘薛。三九已至,卻和暖如春卡睦,著一層夾襖步出監(jiān)牢的瞬間宴胧,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工表锻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恕齐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓瞬逊,卻偏偏與公主長(zhǎng)得像显歧,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子确镊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容