【Leetcode】top 100 图论

基础知识补充

1.图分为有向图和无向图,有权图和无权图;

2.图的表示方法:邻接矩阵适合表示稠密图,邻接表适合表示稀疏图;

   邻接矩阵:

   邻接表:

基础操作补充

1.邻接矩阵:

class GraphAdjacencyMatrix:
    def __init__(self, num_vertices):
        self.num_vertices = num_vertices
        self.matrix = [[0] * num_vertices for _ in range(num_vertices)]

    def add_edge(self, start, end):       # 无向图
        self.matrix[start][end] = 1
        self.matrix[end][start] = 1

2.邻接表:

from collections import defaultdict

class GraphAdjacencyList:
    def __init__(self):
        self.graph = defaultdict(list)

    def add_edge(self, start, end):        # 无向图
        self.graph[start].append(end)
        self.graph[end].append(start)

3.图的遍历:

# 深度优先搜索(DFS):
# 从上到下,递归或栈实现
def dfs(graph, start, visited=None):
    if visited is None:
        visited = set()
    visited.add(start)
    print(start, end=" ")
    for neighbor in graph[start]:
        if neighbor not in visited:
            dfs(graph, neighbor, visited)

# 广度优先搜索(BFS):
# 从左到右,队列实现
from collections import deque

def bfs(graph, start):
    visited = set()
    queue = deque([start])
    visited.add(start)
    while queue:
        current = queue.popleft()
        print(current, end=" ")
        for neighbor in graph[current]:
            if neighbor not in visited:
                queue.append(neighbor)
                visited.add(neighbor)

 题目
200 岛屿数量

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。

 方法一:深度优先搜索 DFS
若当前点是岛屿时,向上下左右四个点做深度搜索;终止条件:越界;当前是水;

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        def dfs(nums, x, y):
            if x<0 or x>len(nums)-1: return 
            if y<0 or y>len(nums[0])-1: return 
            if nums[x][y] =='0':return 
            else:
                nums[x][y] = '0'    # 必须先置0,否则会在两个'1'间连续递归至超过栈长
                dfs(nums, x-1, y)
                dfs(nums, x+1, y)
                dfs(nums, x, y-1)
                dfs(nums, x, y+1)
            
        cnt = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == '1':
                    dfs(grid, i, j)
                    cnt += 1
        return cnt

方法二:广度优先搜索 BFS

若当前点是岛屿时,将其上下左右四个点都加入队列;终止条件:越界;当前是水;

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        def bfs(nums, x, y):
            queue = [(x, y)]
            while queue:
                (x, y) = queue.pop(0)
                if x<0 or x>len(nums)-1: continue 
                elif y<0 or y>len(nums[0])-1: continue 
                elif nums[x][y] =='0':continue 
                else:
                    nums[x][y] = '0'    # 必须先置0,否则会在两个'1'间连续递归至超过栈长
                    queue.append((x-1, y))
                    queue.append((x+1, y))
                    queue.append((x, y-1))
                    queue.append((x, y+1))
        
        cnt = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == '1':
                    bfs(grid, i, j)
                    cnt += 1
        return cnt
 994 腐烂的橘子

在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:

  • 值 0 代表空单元格;
  • 值 1 代表新鲜橘子;
  • 值 2 代表腐烂的橘子。

每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。

第一次遍历将所有新鲜橘子腐烂,统计腐烂次数;第二次遍历统计是否还有剩余的新鲜橘子;(若初始就不含有新鲜橘子呢?)

一次遍历统计新鲜橘子数量的同时记录腐烂橘子的位置(队列);

遍历队列,若当前位置是腐烂橘子则将其上下左右四个点入队,若当前位置是新鲜橘子则将新鲜橘子数量-1再将其上下左右四个点入队;需要将处理过的位置的值置为0,代表不再处理;

class Solution(object):
    def orangesRotting(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        
        cnt, queue = 0, []
        m, n = len(grid), len(grid[0])
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 1:
                    cnt += 1
                elif grid[i][j] == 2:
                    queue.append([i,j])

        if cnt == 0: return 0

        time, stack = -1, []
        while queue:
            [x, y] = queue.pop(0)
            if -1<x<m and -1<y<n and grid[x][y]:
                if grid[x][y] == 1: cnt -= 1
                grid[x][y] = 0            # 不再处理这个点
                stack.append([x-1, y])
                stack.append([x+1, y])
                stack.append([x, y-1])
                stack.append([x, y+1])
            if not queue and stack:
                queue = stack
                time += 1 
                stack = []

        return -1 if cnt else time

计算遍历深度用BFS

207 课程表

你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程  bi 。

  • 例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。

请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。

方法一:广度优先搜索

from collections import deque
from collections import defaultdict

class Solution(object):
    def canFinish(self, numCourses, prerequisites):
        """
        :type numCourses: int
        :type prerequisites: List[List[int]]
        :rtype: bool
        """
        degree = [0]*numCourses    
        maps = defaultdict(list)   
        queue = deque()
        for cur, pre in prerequisites:
            degree[cur] += 1                      # 统计每门课的先修课程数
            maps[pre].append(cur)                 # 记录基础课和对应的进阶课
        for i in range(numCourses):
            if degree[i] == 0: queue.append(i)    # 无先修课程(基础课)时入队
        count = 0
        while queue:
            course = queue.popleft()
            count += 1
            for i in maps[course]:                # 将以course为基础课的进阶课的先修课数-1
                degree[i] -= 1
                if degree[i] == 0:                # 已修完全部基础课
                    queue.append(i)  
        return count == numCourses

方法二:深度优先搜索

class Solution(object):
    def canFinish(self, numCourses, prerequisites):
        """
        :type numCourses: int
        :type prerequisites: List[List[int]]
        :rtype: bool
        """
        degree = [0]* numCourses
        maps = defaultdict(list)
        def dfs(i):
            if degree[i]==-1: return False    # degree[i]==-1 表示会陷入循环
            if degree[i]==1: return True      # degree[i]==1 表示能完成课 
            degree[i]=-1                      # 防止 1-0-1 转回来的情况
            for pre in maps[i]:               # 遍历每门基础课
                if not dfs(pre): return False
            degree[i]=1                       # 该门课可以完成
            return True
        
        for cur, pre in prerequisites:        # 记录先修课和其基础课程
            maps[cur].append(pre)
        for i in range(numCourses):           # 遍历每门课
            dfs(i)
        return sum(degree) == numCourses      # 若每门课都完成应该全为1
208 实现Trie(前缀树)

Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。

请你实现 Trie 类:

  • Trie() 初始化前缀树对象。
  • void insert(String word) 向前缀树中插入字符串 word 。
  • boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false 。
  • boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false 。

核心:使用「边」来代表有无字符,使用「点」来记录是否为「单词结尾」以及「其后续字符串的字符是什么」

class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_end = False

class Trie(object):
    def __init__(self):
        self.root = TrieNode()

    def insert(self, word):
        """
        :type word: str
        :rtype: None
        """
        node = self.root
        for c in word:
            if c not in node.children:
                node.children[c] = TrieNode()
            node = node.children[c]
        node.is_end = True

    def searchPrefix(self, word):
        node = self.root
        for c in word:
            if c not in node.children: return None
            node = node.children[c]
        return node

    def search(self, word):
        """
        :type word: str
        :rtype: bool
        """
        node = self.searchPrefix(word)
        return node is not None and node.is_end

    def startsWith(self, prefix):
        """
        :type prefix: str
        :rtype: bool
        """
        node = self.searchPrefix(prefix)
        return node is not None
 额外补充

flood fill 带你学习Flood Fill算法与最短路模型 - 时间最考验人 - 博客园 (cnblogs.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/507957.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯第1593题——二进制问题

题目描述 小蓝最近在学习二进制。他想知道 1 到 N 中有多少个数满足其二进制表示中恰好有 K 个 1。你能帮助他吗&#xff1f; 输入描述 输入一行包含两个整数 N 和 K。 输出描述 输出一个整数表示答案。 输入输出样例 示例 输入 7 2输出 3评测用例规模与约定 对于 30% …

软件测试工作中需要的Linux知识,一篇文章就够了

01、Linux基础 1、Linux系统简单介绍 Linux是一套免费使用, 支持多用户、多任务、支持多线程和多个核心CPU的操作系统&#xff1b;很多中型, 大型甚至是巨型项目都在使用Linux。 Linux的发行版说简单点就是将Linux与应用软件做一个打包, 目前市面上比较知名的发行版有: Ubun…

Free RTOS day2

1.思维导图 2.使用PWMADC光敏电阻完成光控灯的实验 int adc_val0;//用于保存ADC采样得到的数值 float volt0;//用于保存电压值 int main(void) {MX_GPIO_Init();MX_DMA_Init();MX_TIM1_Init();MX_USART1_UART_Init();MX_ADC_Init();MX_TIM3_Init();HAL_TIM_PWM_Start(&hti…

代码随想录算法训练营第二十七天|131.分割回文串、93.复原IP地址

文档链接&#xff1a;https://programmercarl.com/ LeetCode131.分割回文串 题目链接&#xff1a;https://leetcode.cn/problems/palindrome-partitioning/ 思路&#xff1a;把回溯的树画出来就好很多。startIndex用来控制切割的位置 例如对于字符串abcdef&#xff1a; 组…

实现offsetof宏以及交换一个整数二进制奇偶位的宏

目录 1. offsetof宏2. 交换奇偶位 1. offsetof宏 我们想用宏来实现offsetof函数,首先要了解这个函数的用法。 1.1 offsetof函数的介绍及用法 &#xff08;1&#xff09;功能&#xff1a;用来计算结构体中一个成员在该结构体中的相对起始位置的偏移量&#xff0c;单位是字节。 …

Golang goroutine 同步原语:sync 包让你对并发控制得心应手

在 Go 语言中&#xff0c;不仅有 channel 这类比较易用且高级的同步机制&#xff0c;还有 sync.Mutex、sync.WaitGroup 等比较原始的同步机制。通过它们&#xff0c;我们可以更加灵活地控制数据的同步和多协程的并发。 资源竞争 在一个 goroutine 中&#xff0c;如果分配的内存…

Python多任务处理---多线程

引入 生活中&#xff0c;我们在电脑上打开了一个word, 这个word对操作系统来说就是一个进程。我们在进行word操作的时候&#xff0c;比如在你打字的时候&#xff0c;该word同时可以进行文字检查。发现了没&#xff0c;在同一个进程中&#xff0c;我们也可以进行同时操作。…

【Pytorch学习笔记(二)】张量的创建(补充)

一、知识回顾 我们在博客《张量的创建与访问》中已经讨论了一些张量的创建方法如torch.CharTensor()、torch.FloatTensor()以及torch.zeros()等张量创建方法&#xff0c;但由于其仅仅介绍了cpu版本torch下张量的创建方法和只有具体数据类型张量&#xff0c;本节内容旨在补充gp…

论文速览 | IEEE TCI, 2022 | 单光子级非视距成像:估计强度与优化重建

注1:本文系"计算成像最新论文速览"系列之一,致力于简洁清晰地介绍、解读非视距成像领域最新的顶会/顶刊论文(包括但不限于 Nature/Science及其子刊; CVPR, ICCV, ECCV, SIGGRAPH, TPAMI; Light‑Science & Applications, Optica 等)。 本次介绍的论文是:<2…

【Git】命令行使用体验大大优化的方法

Git的优化使用 相信很多人&#xff0c;在使用git作为版本管理工具时都会感受到它的方便&#xff0c;但是也会有一些问题困扰着我们&#xff0c;让我们觉得使用体验不是很好。我在使用git的过程中就发现了几个问题&#xff1a;写commit费时、怎么做多人开发的代码审查等等。今天…

代码随想录算法训练营第二十五天| 216.组合总和III,17.电话号码的字母组合

题目与题解 216.组合总和III 题目链接&#xff1a;216.组合总和III 代码随想录题解&#xff1a;216.组合总和III 视频讲解&#xff1a;和组合问题有啥区别&#xff1f;回溯算法如何剪枝&#xff1f;| LeetCode&#xff1a;216.组合总和III_哔哩哔哩_bilibili 解题思路&#xf…

Linux之用户账号、用户组和与账号有关的系统文件

目录 一、基本介绍 1.用户和用户组 2.UID和GID 二、 账户管理 1.查看用户的UID和GID 2.添加账户 3.删除账号 4.修改账号 5.账户口令 三、分组管理 1.新增用户组 2.删除用户组 3.修改用户组 4.用户组切换 四、与账号有关的系统文件 1./etc/passwd 2./etc/shado…

组蛋白脱乙酰酶介导的胃癌肿瘤微环境特征及协同免疫治疗(多组学文献学习)

目录 ①HDAC转录组多数据NMF一次聚类 ②ACRG队列中HDAC单独NMF聚类 ③HDS评分在胃癌中的临床特征和基因组特征 ④高 HDS 可能提示胃癌的“热”肿瘤状态 ⑤HDS是胃癌免疫治疗效果的有力预测指标 ⑥单细胞转录组测序揭示了高HDS和低HDS患者的TME ⑦内皮细胞和成纤维细胞可…

Prometheus+grafana环境搭建mysql(docker+二进制两种方式安装)(三)

由于所有组件写一篇幅过长&#xff0c;所以每个组件分一篇方便查看&#xff0c;前两篇 Prometheusgrafana环境搭建方法及流程两种方式(docker和源码包)(一)-CSDN博客 Prometheusgrafana环境搭建rabbitmq(docker二进制两种方式安装)(二)-CSDN博客 1.监控mysql 1.1官方地址:…

文本评估指标 BLEU,METEOR,ROUGE

文本评估指标 这里注意库包的版本&#xff0c;亲测这个很包敏感&#xff0c;所以一定要调好库版本 nltk 3.6.3 如果这个包的版本不对会报错&#xff0c;很难理解的那种 rouge1.0.1 定义函数 import jieba from rouge import Rouge from nltk.translate.meteor_score import …

CrossOver玩游戏会损害电脑吗 CrossOver玩游戏会卡吗 Mac玩游戏 crossover24免费激活

CrossOver是一款可以在macOS上运行Windows应用程序的软件&#xff0c;它利用了Wine技术&#xff0c;无需安装虚拟机或双系统&#xff0c;可以直接在苹果系统下运行Windows游戏。那么&#xff0c;使用CrossOver玩游戏会损害电脑吗&#xff1f;CrossOver玩游戏会卡吗&#xff1f;…

java中:print与println的区别

目录 区别 区别 print是直接打印输出 println是输出后自动回车到下一行 例如 public class test {public static void main(String[] args){System.out.println("换行");System.out.print("不换行");System.out.println();}}——————————————…

Scala第十五章节(递归的相关概述、Scala阶乘案例、Scala斐波那契数列案例、Scala打印目录文件案例)

章节目标 了解递归的相关概述掌握阶乘案例掌握斐波那契数列案例掌握打印目录文件案例 1. 递归 递归指的就是 方法自己调用自己的情况 . 在涉及到复杂操作时, 我们会经常用到它. 在使用递归时, 要注意以下三点: 递归必须有出口, 否则容易造成 死递归 .递归必须要有规律.构造…

跑spark的yarn模式时RM连不上的情况

在linux控制台跑spark on yarn一个测试案例&#xff0c;日志中总显示RM连yarn服务的时候是&#xff1a;0.0.0.0:8032 具体情况如下图&#xff1a; 我问题出现的原因&#xff0c;总结如下&#xff1a; 1.防火墙没关闭&#xff0c;关闭 2.spark-env.sh这个文件的YARN_CONF_DIR…

爱上数据结构:二叉树的基本概念

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;数据结构 ​ 一、树的基本概念 1.概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因 为它看起…