数据结构之栈(一)

栈(stack)队列(Queue)

  • 简单的栈跟队列也是一维结构,类似数组(array);所以分配固定的空间内存,需要考虑空间被占满。存储结构参考链表与数组(线性存储和链接存储)

  • 栈是一个一端受限的线性表。类似竖着的柱子,只能从顶端即栈顶进栈或出栈,所以也能得出后进先出。

  • 队列是能在两端进行操作的线性表。类似一个管道(pipeline),从一端进入另一端推出即先进先出。

存储形式

如下图
在这里插入图片描述

代码表现

栈(stack)

在python语言中通常用list来

stack = ["Amar", "Akbar", "Anthony"]
stack.append("Ram")
stack.append("Iqbal")  #进栈
print(stack)   # ['Amar', 'Akbar', 'Anthony', 'Ram', 'Iqbal']
print(stack.pop()) # Iqbal

队列(Queue)

同上

stack = ["Amar", "Akbar", "Anthony"]
stack.append("Ram")
stack.append("Iqbal")  #进栈
print(stack)   # ['Amar', 'Akbar', 'Anthony', 'Ram', 'Iqbal']
print(stack.pop(0)) # Amar

双端队列(deque)

Deque是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,也可以在两端进行插入;即可以在表的两端进行插入和删除操作。

from collections import deque
deque = deque(["Ram", "Tarun", "Asif", "John"])
print(deque)  #deque(['Ram', 'Tarun', 'Asif', 'John'])
deque.append("Akbar")  # 
deque.appendleft("Raj")
print(deque)  #deque(['Raj', 'Ram', 'Tarun', 'Asif', 'John', 'Akbar'])
print(deque.pop())  #Akbar
print(deque)  #deque(['Raj', 'Ram', 'Tarun', 'Asif', 'John'])
print(deque.popleft())   #Raj
print(deque)  #deque(['Ram', 'Tarun', 'Asif', 'John'])

优先队列

优先队列是一个带有优先级的队列。用权重将队列进行排序。在python中,内置的标准库提供了heapq函数模块和PriorityQueue类模块,其中两个模块都是用了堆(heap)的概念。heap是对于每一个父节点上的值都小于或等于子节点的值的二叉树。(堆是另一种数据结构在此不概述,后续完善)

import heapq  
from queue import PriorityQueue as PQ  # 同步操作,提供锁操作,支持并发的消费者跟生产者
pq = PQ()
pq.put((1, 'a'))
pq.put((2, 'c'))
pq.put((2, 'b'))
pq.put((2, 'b'))
print(pq.queue) # [(1, 'a'), (2, 'b'), (2, 'b'), (2, 'c')]
item0 = pq.get() # (1, 'a')
print(pq.queue) # [(2, 'b'), (2, 'b'), (2, 'c')]

print(pq.qsize()) # 优先队列的尺寸

while not pq.empty():
    print(pq.get())

栈与队列的基本题目

1. 判断括号是否合法(栈)

leetcode 20 给定一个s 包含’(', ‘)’, ‘{’, ‘}’, ‘[‘and’]’ 确定 s是否合法

思路:

给定一个栈,若左边括号则入栈,若右边括号进入则与上一个栈内括号进行消除,若不能消除就Flase,成功则继续,直至栈空。时间复杂度为O(n)。

class Solution:
    def isValid(self, s: str) -> bool:
        stack=['?']
        dic={'(':')','[':']','{':'}','?':'?'}
        for i in s:
            if i in dic:
                stack.append(i)
            else:
                if dic[stack.pop()] != i:
                    return False
        return len(stack)==1

2. 用栈来实现队列功能

leetcode 232 Implement a first in first out (FIFO) queue using only two stacks. The implemented queue should support all the functions of a normal queue (push, peek, pop, and empty).

class MyQueue:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.stack = []
        self.temp = []
    def push(self, x: int) -> None:
        """
        Push element x to the back of queue.
        """
        self.temp.append(x)    # 临时stack 存值

    def pop(self) -> int:
        """
        Removes the element from in front of queue and returns that element.
        """
        if not self.stack:
            while self.temp:
                self.stack.append(self.temp.pop())  # 反向存值
        return self.stack.pop()  # 先进先出
    def peek(self) -> int:
        """
        Get the front element.
        """
        if not self.stack:
            while self.temp:
                self.stack.append(self.temp.pop())
        return self.stack[-1]
    def empty(self) -> bool:
        """
        Returns whether the queue is empty.
        """
        return not self.stack and not self.temp

3. 最小栈

leetcode 155 Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

Implement the MinStack class:

  • MinStack() initializes the stack object.
  • void push(int val) pushes the element val onto the stack.
  • void pop() removes the element on the top of the stack.
  • int top() gets the top element of the stack.
  • int getMin() retrieves the minimum element in the stack.
class MinStack:

    def __init__(self):
        self.q=[]
    def push(self, val: int) -> None:
        min_value=self.getMin()
        if  min_value==None or val < min_value:
            min_value=val
        self.q.append((val,min_value))  # 栈存入当前值与最小值tuple

    def pop(self) -> None:
        self.q.pop()

    def top(self) -> int:
        if len(self.q)==0:
            return None
        else:
            return self.q[-1][0]

    def getMin(self) -> int:
        if not len(self.q):
            return None
        else:
            return self.q[-1][1]
        


# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()

4. 最长有效括号

Leetcode 32

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

  • 动态规划
class Solution:
    def longestValidParentheses(self, s: str) -> int:
        dp= [0] * len(s)
        len_s=len(s)
        for i in range(1,len_s):
            if s[i] ==')':
                if s[i-1]=='(':      # 形成一个有效括号对
                    dp[i]=dp[i-2]+2
                elif i-1-dp[i-1] >0 and s[i-dp[i-1]-1]=='(':  #不出界以及跨越两个字符之后又是一个有效括号
                    dp[i]=dp[i-1]+2+(dp[i-dp[i-1]-2] if i-dp[i-1]-2 >0 else 0)  # 取两种判断的和,确定未出界
				return max(dp) if s else 0

class Solution:
    def longestValidParentheses(self, s: str) -> int:
    	  stk, max_len = [(")", -1)], 0
        for i in range(len(s)):
            if s[i] == ")" and stk[-1][0] == "(":
                stk.pop()
                max_len = max(max_len, i - stk[-1][1])   # 用序列号获取max_len
            else:
                stk.append((s[i], i))
        return max_len

5. 接雨水

Leetcode 42

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.

class Solution:
    def trap(self, height: List[int]) -> int:  
        stack=[]
        res=0
        for i in range(len(height)):
            while stack and height[i]>height[stack[-1]]:
                h=height[stack.pop()]       # 单调递减栈
                if not stack:
                    break
                res +=min(height[i],height[stack[-1]]-h)*(i-1-stack[-1])
            stack.append(i)
        return res
      
  • 双指针
class Solution:
    def trap(self, height: List[int]) -> int:  
      if not height or len(height)<3:
        return 0
      volume=0
      left,right=0,len(height)-1
      l_max,r_max=height[left],height[right]
      while left<right:
        l_max,r_max=max(l_max,height[left]),max(r_max,height[right])
        if l_max<=r_max:
          volume += l_max-height[left]
          left +=1
        else:
          volume +=r_max-height[right]
          right -=1
      return volume
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值