栈和队列 01 02 03

yuhao0451 / 2023-09-05 / 原文

225:

class MyStack(object):

    def __init__(self):
        self.q1 = deque() 
        self.q2 = deque() 

    def push(self, x):
        """
        :type x: int
        :rtype: None
        """
        self.q1.append(x)
         

    def pop(self):
        """
        :rtype: int
        """
        #确认不为空
        if q1.empty():
            return None 
        #将q1 除最后一位以外的元素 append 进 q2 中
        #此时q1 剩下的元素为需要pop出去的元素
        for i in range(len(self.q1) - 1):
            self.q2.append(self.q1.popleft()) 
        #交换q1, q2中的元素
        self.q1, self.q2 = self.q2, self.q1 
        #pop 
        return self.q2.popleft() 
        
    def top(self):
        """
        :rtype: int
        """
        if self.empty():
            return None 

        return self.q1[-1]


    def empty(self):
        """
        :rtype: bool
        """
        return self.q1 == []

20:

相关阅读:https://leetcode.cn/problems/valid-parentheses/solutions/89144/zhu-bu-fen-xi-tu-jie-zhan-zhan-shi-zui-biao-zhun-d/

def isValid(s):
    d = {')':'(', ']':'[', '}':'{'} 
    stack = [] 
    for i in s :
        if stack and i in d:
            #如果栈顶的元素和d[i]相同,说明已经匹配上了一对
            if stack[-1] == d[i] :
                stack.pop() 
            else : 
                return False 
        else :
            #将s中的元素入栈
            stack.append(i) 

    return not stack 

1047:

class Solution(object):
    def removeDuplicates(self, s):
        """
        :type s: str
        :rtype: str
        """
        #理解了20题就很好理解这个题了
        stack = [] 
        for i in s:
            if stack and stack[-1] == i:
                stack.pop()

            else:
                stack.append(i) 

        return "".join(stack)

150:

参考答案:https://programmercarl.com/0150.%E9%80%86%E6%B3%A2%E5%85%B0%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B1%82%E5%80%BC.html

设计原理:如果是数字则存入stack中,如果是操作符,则pop出当前stack栈顶的两个数字进行数字运算,之后将结果重新push 进 栈中。

class Solution(object):
    def evalRPN(self, tokens):
        stack = []
        #遍历字符串,如果是数字就执行try
        #如果是操作符就执行 except
        for token in tokens:
            try:
                stack.append(int(token))
            except:
                num2 = stack.pop()
                num1 = stack.pop()
                stack.append(self.evaluate(num1, num2, token))
        return stack[0]

    def evaluate(self, num1, num2, op):
        if op == "+":
            return num1 + num2
        elif op == "-":
            return num1 - num2
        elif op == "*":
            return num1 * num2
        elif op == "/":
            return int(num1 / float(num2))

s = Solution() 
s.evalRPN(tokens)

239: 

相关阅读:https://programmercarl.com/0347.%E5%89%8DK%E4%B8%AA%E9%AB%98%E9%A2%91%E5%85%83%E7%B4%A0.html#%E6%80%9D%E8%B7%AF

class Solution(object):
    def topKFrequent(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        if len(nums) == 0:
            return [] 
    
        d = {} 
        for num in nums :
            if num not in d:
                d[num] = 1 
            else:
                d[num] += 1
        #根据value来对字典排序
        ls = sorted(d.items(), key=lambda x:x[1], reverse=True)  
        res = [] 
        for i in range(k) :
            res.append(ls[i][0]) 

        return res 

239: so hard 

class Solution:
    def maxSlidingWindow(self, nums, k):
        ans = []
        dq = deque()
        
        for i in range(len(nums)):
            # 只要当前遍历的元素的值比队尾大,让队尾出队列,
            # 最终队列中的最小元素是大于当前元素的
            while dq and dq[-1] < nums[i]:
                dq.pop()
            # 当前遍历的元素入队列, 此时队列中的元素一定是有序的,队列头部最大
            dq.append(nums[i])
            if i >= k - 1:
                # 如果窗口即将失效(下一次循环要失效)的值与当前对列头部的值相同,那么将对头的值出队列,
                # 注意只pop一次,可能两个4,相邻同时是最大值,
                ans.append(dq[0])
                # 从队列中删除即将失效的数据
                if nums[i - k + 1] == dq[0]:
                    dq.popleft()
        return ans