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

【栈】

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]

原文地址:https://www.cnblogs.com/deeplearning-man/p/10859317.html

时间: 2024-08-29 19:42:28

数据结构与算法:栈+队列+递归的相关文章

数据结构与算法--栈、队列(队列)

Hello,everybody.我们又见面了.今天我们来学习一下队列这个数据结构,let's Go,开始我们的征程吧. 首先,举两个生活中的常见例子.相信大家,在用电脑工作娱乐时,都会碰到这样的现象.当我们点击程序或进行其他操作时,电脑处于死机状态.正当我们准备Reset时,它突然像打了鸡血似的,突然把刚才我们的操作,按顺序执行了一遍.之所以会出现这个现象,是因为操作系统的多个程序,需要通过一个管道输出,而按先后顺序排队造成的. 还有有个例子,在我们打客服热线时,有时会出现等待的现象.当其他客户

【Java数据结构学习笔记之二】Java数据结构与算法之队列(Queue)实现

  本篇是数据结构与算法的第三篇,本篇我们将来了解一下知识点: 队列的抽象数据类型 顺序队列的设计与实现 链式队列的设计与实现 队列应用的简单举例 优先队列的设置与实现双链表实现 队列的抽象数据类型   队列同样是一种特殊的线性表,其插入和删除的操作分别在表的两端进行,队列的特点就是先进先出(First In First Out).我们把向队列中插入元素的过程称为入队(Enqueue),删除元素的过程称为出队(Dequeue)并把允许入队的一端称为队尾,允许出的的一端称为队头,没有任何元素的队列

javascript数据结构与算法---栈

在上一遍博客介绍了下列表,列表是最简单的一种结构,但是如果要处理一些比较复杂的结构,列表显得太简陋了,所以我们需要某种和列表类似但是更复杂的数据结构---栈.栈是一种高效的数据结构,因为数据只能在栈顶添加或删除,所以这样操作很快,而且容易实现. 一:对栈的操作. 栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端陈为栈顶.比如餐馆里面洗盘子,只能先洗最上面的盘子,盘子洗完后,也只能螺到这一摞盘子的最上面.栈被称为 "后入先出"(LIFO)的数据结构. 由于栈具有后入先出的特点

JavaScript数据结构和算法----栈

前言 栈是一种遵循后进先出(LIFO)原则的有序集合,新添加的或待删除的元素都保存在栈的末尾,称作栈顶,另外一端就叫栈底.在栈里,新元素都靠近栈顶,旧元素都接近栈底.可以想象桌上的一叠书,或者厨房里的堆放的盘子. 一.栈的创建 可以创建一个类来表示栈 //1.创建一种数据结构来保存栈里面的数据,这里选择数组 //2.声明一些栈的方法 // push(element(s)) : 添加一个或一些元素到栈顶 // pop() : 移除栈顶的元素,同时返回被移除的元素. // peek() : 返回栈顶

javascript数据结构与算法——栈

前言: 栈就是和列表类似的一种数据结构,不过栈的特点是'后人先出'.栈是一种高效的数据结构,因为数据只能在栈顶添加或删除,所以这样操作很快,而且容易实现. 1. 栈的介绍: 栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端被称为栈顶,另一端称为栈底.比如饭店罗盘子,只能从最上面取盘子,盘子洗干净后,也只能罗在做上面.栈被称为一种先入后出的(LIFO)的数据结构. 示意图:

数据结构与算法之队列、栈

除了数组.链表,线性的数据结构中还有很重要的几种结构:队列.栈. 队列,一种先进先出的数据结构(FIFO),其实队列可以看成是一个两个口的管道,从一个口进,另一个口出,先进去的必定得在另一个口先出去,否则后面的都出不去:栈,一种后进先出的数据结构(LIFO),栈更像是只有一个口的管道,只有一个开口可以进出,先进去的在底部,所以必须得让后进去的先出去,它才能出去. 实现队列和栈可以用顺序存储结构,也可以用链式存储结构.这里采用的是链表来实现,同时还有用两个栈实现一个队列和用两个队列实现一个栈的算法

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

一.简介 众所周知,线性表是数据结构的基础,通常有两种实现方式:数组和链表.栈和队列是最常用的数据结构,它们基于线性表实现. 二.栈 定义:栈是限定仅在表尾进行插入和删除操作的线性表,即FILO. 栈被经常类比于弹夹,即先被压如弹夹的子弹最后被打出.根据线性表的实现方式得知,栈的实现方式有两种:数组实现和链表实现. 栈的数组实现: package basic.data_structure.cha01; /** * 栈:先进后出(FILO),只允许在栈顶操作元素 * 栈的基本操作: * 初始化栈.

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

(摘录加总结)------ 栈和队列不属于基础的数据结构,它们都属于线性表. 一.栈 对于栈存储操作元素只能在栈结构的一端进行元素的插入和删除,是一种性质上的线性表结构.按照“先进后出”的原则进行存储数据.先进的元素在栈底,后进的元素在栈顶.需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来).比较常规的说明是:栈底固定,而栈顶浮动:栈中元素个数为零时称为空栈.插入一般称为进栈(PUSH),删除则称为退栈(POP). 栈的实现结构包括顺序结构实现和链式结构实现.前者依据的是数组,后者

【数据结构与算法】二叉树递归与非递归遍历(附完整源码)(转)

转自:http://blog.csdn.net/ns_code/article/details/12977901 二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的.二叉树有前.中.后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的).下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍历方式的非递归实现. 一.三种遍历方式的递