20220218_datawhale34期_leetcode_3栈

3 栈

1.1基础

只允许在一端进行插入或删除操作的线性表

首先,栈是一种线性表,但限定这种线性表只能在某一段进行插入和删除操作

  • 时间复杂度

    • Push (入栈):O(1)
    • Pop (出栈):O(1)
    • Access (访问栈顶):O(1)
  • 两种实现方式

    • 顺序栈:采用顺序存储结构可以模拟栈存储数据的特点,从而实现栈存储结构;
    • 链栈:采用链式存储结构实现栈结构
  • 区别: 物理存储位置区别--------------顺序栈底层采用的是数组,链栈底层采用的是链表

  • 顺序栈实现及基本操作

class Stack:
    #初始化
    def __init__(self, size = 100):
        self.top = -1
        self.size = size
        self.stack = []
    
    #判断是否为空
    def is_None(self):
        return self.top == -1
    
    #判断是否满栈
    def is_full(self):
        return self.top + 1 == self.size
    
    #入栈
    def push(self, val):
        if self.is_full():
            raise Exception("Stack is full!")
        else:
            self.stack.append(val)
            self.top += 1
            
    #出栈
    def pop(self):
        if self.is_None():
            raise Exception("Stack is empty")
        else:
            self.stack.pop()
            self.top -= 1
            
            
    #获得栈顶
    def peek(self):
        if self.is_None():
            raise Exception("Stack is empty")
        else:
            return self.stack[self.top]
  • 链栈实现及基本操作
class ListNode:
    def __init__(self, val):
        self.val = val
        self.next = next
    
class Stack:
    #初始化
    def __init__(self):
        self.top = None
        
    def is_None(self):
        return self.top == None
    
    def push(self, val):
        cur = ListNode(val)
        cur.next = self.top
        self.top = cur
        
    def pop(self):
        if self.is_None():
            raise Exception("Stack is empty")
        else:
            cur = self.top
            self.top = self.top.next
            del cur
            
    def peek(self):
        if self.is_None():
            raise Exception("Stack is empty")
        else:
            return self.top.val
    

1.2 题目

1.2.1 20 . 有效的括号

  • 思路: 哈希 + 栈 >>>> 利用哈希记录括号合法相关关系 >>> 左括号优先入栈, 直到出现第一个右括号 >>> 判断第一右括号是否与栈顶合法配对 >>> 配对成功栈顶出栈 >>> 直到栈非空则False, 栈为空则True
class Solution:
    def isValid(self, s: str) -> bool:
        d = { "}":"{",
              "]":"[",
              ")":"(" }
        stack = []
        for k in s:
            if k not in d:
                stack.append(k)
            else:
                if stack and d[k] == stack[-1]:
                    stack.pop()
                else:
                    return False
        return not stack

1.2.2 150 . 逆波兰表达式求值

  • 思路: 建立新栈 >>> 数字入栈, 遇到符号考虑stack[-1]stack[-2]的运算 >>> 注意: isdigit()只能判断正数 ; 除法应该用int()确保整型
class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        stack = []
        for token in tokens:
            if token[-1].isdigit():  # 考虑到负数使用token[-1]
                stack.append(int(token))
            else:
                p = stack.pop()
                if token == "+":
                    stack[-1] += p
                elif token == "-":
                    stack[-1] -= p
                elif token == "*":
                    stack[-1] *= p
                elif token == "/":
                    stack[-1] = int(stack[-1] * 1/p)
        return stack[-1]

1.2.3 155 . 最小栈

  • 思路: 考虑利用两个栈 >>> minstack[-1]来表示当前链表最小值 >>> 当pop,push栈时更新minstack
class MinStack:

    def __init__(self):
        self.stack = []
        self.minstack = []

    def push(self, val: int) -> None:
        self.stack.append(val)
        if not self.minstack or self.minstack[-1] >= val:
            self.minstack.append(val)
        
    def pop(self) -> None:
        if self.stack[-1] == self.minstack[-1]:
            self.minstack.pop()
        self.stack.pop()

    def top(self) -> int:
        return self.stack[-1] 

    def getMin(self) -> int:
        return self.minstack[-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()

1.2.4 844 . 比较含退格的字符串

  • 思路一: 栈 >>> 两栈对比是否相等解决
class Solution:
    def backspaceCompare(self, s: str, t: str) -> bool:
        stack_1, stack_2 = [], []
        for i in s:
            if stack_1 and i == "#":
                stack_1.pop()
            elif i != '#':
                stack_1.append(i)
        for j in t:
            if stack_2 and j == "#":
                stack_2.pop()
            elif j != '#':
                stack_2.append(j)
        return stack_1 == stack_2
  • 思路二: 空间复杂 O(1) ----- 快慢指针 >>>> fast遍历字符串, 遇到# slow左移, 否则右移
class Solution:
    def backspaceCompare(self, s: str, t: str) -> bool:
        def backspace(s):
            fast, slow = 0, 0
            s = list(s)
            while fast < len(s):
                if s[fast] != '#':
                    s[slow] = s[fast]
                    slow += 1
                elif slow > 0: 
                    slow -= 1
                fast += 1
            return s[:slow]
        return backspace(s) == backspace(t)

1.2.5 227 . 基本计算器 II

  • 思路:
    加法 >>> num入栈
    减法 >>> -num入栈
    乘法 >>> 栈顶*num 入栈
    除法 >>> 栈顶 / num 入栈
    最后计算栈和
class Solution:
    def calculate(self, s: str) -> int:
        op = '+'
        stack = []
        num = 0
        for i in range(len(s)):
            if s[i].isdigit():
                num = num * 10 + int(s[i])
            if i == len(s) - 1 or s[i] in "+-*/":
                if op == '+':
                    stack.append(num)
                elif op == '-':
                    stack.append(-num)
                elif op == '*':
                    stack.append(stack.pop() * num)
                elif op == '/':
                    stack.append(int(stack.pop() / num))
                num = 0
                op = s[i]
        return sum(stack)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值