数据结构与算法:栈+队列+递归

Posted deeplearning-man

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法:栈+队列+递归相关的知识,希望对你有一定的参考价值。

【栈】

Python实现:

1. 用数组实现一个顺序栈

class SStack():
    def __init__(self):
        self._elems = []
    def is_empty(self):
        return self._elems == []
    def top(self):
        if self._elems == []:
            raise StackUnderflow("in SStack.top()")
        return self._elems[-1]
    def push(self, elem):
        self._elems.append(elem)
    def pop(self):
        if self._elems == []:
            raise StackUnderflow("in SStack.pop()")
        return self._elems.pop()
class StackUnderflow(ValueError):
    pass

 

2. 用链表实现一个链式栈

#表头作为栈顶,表尾作为栈底
class LStack():
    def __init__(self):
        self._top = None
    def is_empty(self):
        return self._top is None
    def top(self):
        if self._top == []:
            raise StackUnderflow("in LStack.top()")
        return self._top.elem
    def push(self, elem):
        self._top = LNode(elem, self._top)
    def pop(self):
        if self._top is None:
            raise StackUnderflow("in LStack.pop()")
        p =self._top
        self._top = p.next
        return p.elem
class StackUnderflow(ValueError):
    pass

 

3. 编程模拟实现一个浏览器的前进、后退功能

 

  练习:

  1. 有效的括号 https://leetcode-cn.com/problems/valid-parentheses/

  思路:栈+字典

class Solution:
    def isValid(self, s: str) -> bool:
        stack=[]
        dic={[:],{:},(:)}
        for parenthese in s:
            if parenthese in dic:
                stack.append(parenthese)
            elif stack==[] or parenthese != dic[stack.pop()]:
                return False
        return stack==[]

 

  2. 最长有效的括号 [作为可选] https://leetcode-cn.com/problems/longest-valid-parentheses/

  思路:栈

class Solution:
    def longestValidParentheses(self, s: str) -> int:
        #先找到所有可以匹配的索引号,然后找出最长连续数列
        if not s:
            return 0
        res = []
        stack = []
        for i in range(len(s)):
            if stack and s[i] == ")":
                res.append(stack.pop())
                res.append(i)
            if s[i] == "(":
                stack.append(i)
        res.sort()
        #print(res)
        i = 0
        ans = 0
        n = len(res)
        while i < n:
            j = i
            while j < n - 1 and res[j + 1] == res[j] + 1:
                j += 1
            ans = max(ans, j - i + 1)
            i = j + 1
        return ans

 

  3. 逆波兰表达式求值 https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/

  思路:栈+字典

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        f1 = lambda a,b:a+b
        f2 = lambda a,b:a-b
        f3 = lambda a,b:a*b
        f4 = lambda a,b:int(a/b)
        dic = {+:f1,-:f2,*:f3,/:f4}
        stack = []
        for i in tokens:
            if i in dic:
                a = stack.pop()
                b = stack.pop()
                stack.append(dic[i](b,a))
            else:
                i = int(i)
                stack.append(i)
        return stack[-1]

 

【队列】

  1. 用数组实现一个顺序队列
  2. 用链表实现一个链式队列
  3. 实现一个循环队列

  练习:

  1. 设计一个双端队列 https://leetcode-cn.com/problems/design-circular-deque/

  思路:list

class MyCircularDeque:

    def __init__(self, k: int):
        """
        Initialize your data structure here. Set the size of the deque to be k.
        """
        self.queue=[]
        self.size=k

    def insertFront(self, value: int) -> bool:
        """
        Adds an item at the front of Deque. Return true if the operation is successful.
        """
        if not self.isFull():
            self.queue.insert(0,value)
            return True
        else:
            return False

    def insertLast(self, value: int) -> bool:
        """
        Adds an item at the rear of Deque. Return true if the operation is successful.
        """
        if not self.isFull():
            self.queue.append(value)
            return True
        else:
            return False

    def deleteFront(self) -> bool:
        """
        Deletes an item from the front of Deque. Return true if the operation is successful.
        """
        if not self.isEmpty():
            self.queue.pop(0)
            return True
        else:
            return False

    def deleteLast(self) -> bool:
        """
        Deletes an item from the rear of Deque. Return true if the operation is successful.
        """
        if not self.isEmpty():
            self.queue.pop()
            return True
        else:
            return False

    def getFront(self) -> int:
        """
        Get the front item from the deque.
        """
        if self.isEmpty():
            return -1
        else:
            return self.queue[0]

    def getRear(self) -> int:
        """
        Get the last item from the deque.
        """
        if self.isEmpty():
            return -1
        else:
            return self.queue[-1]

    def isEmpty(self) -> bool:
        """
        Checks whether the circular deque is empty or not.
        """
        return len(self.queue) == 0

    def isFull(self) -> bool:
        """
        Checks whether the circular deque is full or not.
        """
        return len(self.queue) == self.size

 

  2. 滑动窗口最大值 https://leetcode-cn.com/problems/sliding-window-maximum/

  思路:1.暴力法 2.双端队列

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        ‘‘‘
        #暴力法
        if nums==[]:
            return []
        n=len(nums)
        res=[]
        for i in range(n-k+1):
            window=nums[i:i+k]
            res.append(max(window))
        return res
         if not nums or k == 0:
            return []
        if k == 1:
            return nums
        ‘‘‘
        #双端队列
        if nums == [] or k == 0:
            return []
        if k == 1:
            return nums
        #队列里保存可能是最大值的索引
        queue = [0]
        # 存放窗口中最大值
        res = []
        for i in range(1,len(nums)):
            #判断队首对应的元素是否已经滑出窗口
            if i-queue[0] >= k:
                queue.pop(0)
            #保证当前最大值的索引是第一个。遇到一个新数时,将它与队尾元素比较,如果大于队尾元素,则丢掉队尾元素,继续重复比较,直到新数小于队尾元素,或者队列为空为止,将新数下标放入队列
            while queue and nums[queue[-1]] < nums[i]:
                queue.pop()
            queue.append(i)
            if i >= k-1:
                res.append(nums[queue[0]])
        return res

 

【递归】

1. 编程实现斐波那契数列求值 f(n)=f(n-1)+f(n-2)

def fib_recur(n):
  if n <= 1:
    return n
  return fib_recur(n-1) + fib_recur(n-2)

 

2. 编程实现求阶乘 n!

def fact(n):
    if n == 0:
        return 1
    else:
        return n * fact(n - 1)

 

3. 编程实现一组数据集合的全排列

def perm(l):  
    if(len(l)<=1):  
        return [l]  
    r=[]  
    for i in range(len(l)):  
        s=l[:i]+l[i+1:]  
        p=perm(s)  
        for x in p:  
            r.append(l[i:i+1]+x)  
    return r

 

  练习:

  1. 爬楼梯 https://leetcode-cn.com/problems/climbing-stairs/

  思路:1.递归 2.动态规划

class Solution:
    def climbStairs(self, n: int) -> int:
        ‘‘‘
        递归
        if n==1:
            return 1
        elif n==2:
            return 2
        else:
            return self.climbStairs(n-1)+self.climbStairs(n-2)
        ‘‘‘
        #动态规划
        nums=[1,1]
        for i in range(2,n+1):
            nums.append(nums[i-1]+nums[i-2])
        return nums[n]

 

以上是关于数据结构与算法:栈+队列+递归的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法--栈与队列

数据结构与算法

数据结构和算法之栈和队列一:两个栈模拟一个队列以及两个队列模拟一个栈

数据结构与算法--必知必会

数据结构栈与队列---栈的应用(递归和分治思想)

[NEFU 数据结构]阶段一复习