720220120_datawhale33期_leetcode刷题_8队列及BFS

八 队列及BFS

请添加图片描述Images Source: https://realpython.com/

来源

Datewhale33期__LeetCode 刷题 :

1 队列

1.1 基础知识

  • 与栈结构不同的是,队列的两端都"开口",要求数据只能从一端进,从另一端出

在这里插入图片描述
遵循 “先进先出” 的原则

  • 实现

    • 顺序队列:在顺序表的基础上实现的队列结构;
    • 链队列:在链表的基础上实现的队列结构;

  • 双端队列

双端队列又名double ended queue,简称deque,双端队列没有队列和栈这样的限制级,它允许两端进行入队和出队操作,也就是说元素可以从队头出队和入队,也可以从队尾出队和入队。

在这里插入图片描述


  • 优先队列

优先队列是基于二叉堆实现, 优先指的是按某种优先级优先出列

  • "优先级"可以是自己定义的一个元素属性
  • 许多数据结构都可以用来实现优先队列,例如二叉堆、二叉平衡树等

  • 时间复杂度

栈、队列

  • Push (入栈、入队):O(1)
  • Pop (出栈、出队):O(1)
  • Access (访问栈顶、访问队头):O(1)

双端队列

  • 队头、队尾的插入、删除、访问也都是O(1)

优先队列

  • 访问最值:O(1)
  • 插入:一般是◦ (logN),-些高级数据结构可以做到O(1)
  • 取最值: O(logN)

  • python中
    栈、队列、双端队列可以用 list 实现
    优先队列可以用 heapq 库

  • 队列的顺序存储实现

class Queue:
    # 初始化空队列
    def __init__(self, size=100):
        self.size = size
        self.queue = [None for _ in range(size)]
        self.front = -1
        self.rear = -1
        
    # 判断队列是否为空
    def is_empty(self):
        return self.front == self.rear
    
    # 判断队列是否已满
    def is_full(self):
        return self.rear + 1 == self.size
    
    # 入队操作
    def enqueue(self, value):
        if self.is_full():
            raise Exception('Queue is full')
        else:
            self.rear += 1
            self.queue[self.rear] = value
            
    # 出队操作
    def dequeue(self):
        if self.is_empty():
            raise Exception('Queue is empty')
        else:
            self.front += 1
            return self.queue[self.front]
        
    # 获取队头元素
    def front_value(self):
        if self.is_empty():
            raise Exception('Queue is empty')
        else:
            return self.queue[self.front + 1]
    
    # 获取队尾元素
    def rear_value(self):
        if self.is_empty():
            raise Exception('Queue is empty')
        else:
            return self.queue[self.rear]

1.2 相关题目

1.2.1 622 . 设计循环队列
class MyCircularQueue:

    def __init__(self, k: int):
        self.size = k + 1
        self.queue = [None for _ in range(k + 1)]
        self.front = 0
        self.rear = 0


    def enQueue(self, value: int) -> bool:
        if self.isFull():
            return False
        else:
            self.rear = (self.rear + 1) % self.size
            self.queue[self.rear] = value
            return True


    def deQueue(self) -> bool:
        if self.isEmpty():
            return False
        else:
            self.queue[self.front] = None
            self.front = (self.front + 1) % self.size
            return True


    def Front(self) -> int:
        if self.isEmpty():
            return -1
        else:
            value = self.queue[(self.front + 1) % self.size]
            return value


    def Rear(self) -> int:
        if self.isEmpty():
            return -1
        else:
            value = self.queue[self.rear]
            return value


    def isEmpty(self) -> bool:
        return self.front == self.rear


    def isFull(self) -> bool:
        return (self.rear + 1) % self.size == self.front

2 BFS

  • 广度优先遍历
    (1)从图中的某个初始点 v0 出发,首先访问初始点 v0。
    (2)接着访问该顶点的所有未访问过的邻接点 v01 v02 v03 ……v0n。
    (3)然后再选择 v01 v02 v03 ……v0n,访问它们的未被访问的邻接点,v010 v011 v012……v01n。
    (4)直到所有与初始顶点 v 联通的顶点都被访问。

在这里插入图片描述

2.1 相关题目

2.1.1 463 . 岛屿的周长
  • 思路: 利用BFS >>> 搜索出出界或grid[nx][ny] == 0 >>> 周长加一
class Solution:
    def islandPerimeter(self, grid: List[List[int]]) -> int:
        from collections import deque
        m, n = len(grid), len(grid[0])
        visvited = [[False] * n for _ in range(m)]
        def bfs(i, j):
            count = 0
            q = deque()
            q.append([i, j])
            visvited[i][j] = True
            dr = [(-1, 0), (0, 1), (0, -1), (1, 0)]
            while q:
                x, y = q.popleft()
                for k in dr:
                    nx = x + k[0]
                    ny = y + k[1]
                    if nx < 0 or ny < 0 or nx >= m or ny >= n or not grid[nx][ny]:
                        count += 1
                        continue
                    if visvited[nx][ny]: continue
                    q.append([nx, ny])
                    visvited[nx][ny] = True
            return count
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 1:
                    return bfs(i, j)
2.1.2 752 . 打开转盘锁
  • 思路: 哈希 + BFS
class Solution:
    def openLock(self, deadends: List[str], target: str) -> int:
        dead = set(deadends)
        q = collections.deque(["0000"])
        visvited = {"0000": 0}
        while q:
            s = q.popleft()
            if s in dead: continue
            for i in range(4):
                for j in (-1, 1):
                    change = (int(s[i]) + j) % 10
                    ns = s[:i] + str(change) + s[i + 1:]
                    if ns not in visvited:
                        visvited[ns] = visvited[s] + 1
                        q.append(ns)
                    if ns == target:
                        return visvited[ns]
        return -1
2.1.3 542 . 01 矩阵
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值