数据结构与算法:栈+队列+递归
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. 设计一个双端队列 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]
以上是关于数据结构与算法:栈+队列+递归的主要内容,如果未能解决你的问题,请参考以下文章