LeetCode力扣刷题——指针三剑客之三:图

news2025/1/17 1:15:22


一、数据结构介绍

        作为指针三剑客之三,图是树的升级版。图通常分为有向(directed)或无向(undirected),有 循环(cyclic)或无循环(acyclic),所有节点相连(connected)或不相连(disconnected)。树即是 一个相连的无向无环图,而另一种很常见的图是有向无环图(Directed Acyclic Graph,DAG)。

有向无环图样例

         图通常有两种表示方法。假设图中一共有 n 个节点、m 条边。

        第一种表示方法是邻接矩阵 (adjacency matrix):我们可以建立一个 n× n 的矩阵 G,如果第 i 个节点连向第 j 个节点,则 G[i][j] = 1,反之为 0;如果图是无向的,则这个矩阵一定是对称矩阵,即 G[i][j] = G[j][i]。

        第二种表示 方法是邻接链表(adjacency list):我们可以建立一个大小为 n 的数组,每个位置 i 储存一个数组或者链表,表示第 i 个节点连向的其它节点。邻接矩阵空间开销比邻接链表大,但是邻接链表不支持快速查找 i 和 j 是否相连,因此两种表示方法可以根据题目需要适当选择。除此之外,我们也可以直接用一个 m × 2 的矩阵储存所有的边。


二、经典问题

1. 二分图

        二分图算法也称为染色法,是一种广度优先搜索。如果可以用两种颜色对图中的节点进行着 色,并且保证相邻的节点颜色不同,那么图为二分。

785. 判断二分图

785. Is Graph Bipartite?

        存在一个无向图 ,图中有 n 个节点。其中每个节点都有一个介于 0 到 n - 1 之间的唯一编号。给你一个二维数组 graph ,其中 graph[u] 是一个节点数组,由节点 u 的邻接节点组成。形式上,对于 graph[u] 中的每个 v ,都存在一条位于节点 u 和节点 v 之间的无向边。该无向图同时具有以下属性:
        不存在自环(graph[u] 不包含 u)。
        不存在平行边(graph[u] 不包含重复值)。
        如果 v 在 graph[u] 内,那么 u 也应该在 graph[v] 内(该图是无向图)
        这个图可能不是连通图,也就是说两个节点 u 和 v 之间可能不存在一条连通彼此的路径。
        二分图 定义:如果能将一个图的节点集合分割成两个独立的子集 A 和 B ,并使图中的每一条边的两个节点一个来自 A 集合,一个来自 B 集合,就将这个图称为 二分图 。

        如果图是二分图,返回 true ;否则,返回 false 。

        利用队列和广度优先搜索,我们可以对未染色的节点进行染色,并且检查是否有颜色相同的 相邻节点存在。注意在代码中,我们用 0 表示未检查的节点,用 1 和 2 表示两种不同的颜色。

        注意输入的是邻接链表表示的图。

class Solution {
public:
    bool isBipartite(vector<vector<int>>& graph) {
        int n = graph.size();
        if(n == 0)  return true;
        vector<int> color(n, 0);
        queue<int> q;
        for(int i=0; i<n; ++i){
            if(color[i] == 0){
                q.push(i);
                color[i] = 1;
            }
            while(!q.empty()){
                int node = q.front();
                q.pop();
                for(const int& j: graph[node]){
                    if(color[j] == 0){
                        q.push(j);
                        color[j] = color[node] == 2? 1: 2;
                    }else if(color[j] == color[node]){
                        return false;
                    }
                }
            }
        }
        return true;
    }
};

2. 拓扑排序

        拓扑排序(topological sort)是一种常见的,对有向无环图排序的算法。给定有向无环图中的 N 个节点,我们把它们排序成一个线性序列;若原图中节点 i 指向节点 j,则排序结果中 i 一定在 j 之前。拓扑排序的结果不是唯一的,只要满足以上条件即可。

210. 课程表 II

210. Course Schedule II

        现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。

        例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示:[0,1] 。
        返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组 。

        我们可以先建立一个邻接矩阵表示图,方便进行直接查找。这里注意我们将所有的边反向, 使得如果课程 i 指向课程 j,那么课程 i 需要在课程 j 前面先修完。这样更符合我们的直观理解。 拓扑排序也可以被看成是广度优先搜索的一种情况:我们先遍历一遍所有节点,把入度为 0 的节点(即没有前置课程要求)放在队列中。在每次从队列中获得节点时,我们将该节点放在目 前排序的末尾,并且把它指向的课程的入度各减 1;如果在这个过程中有课程的所有前置必修课 都已修完(即入度为 0),我们把这个节点加入队列中。当队列的节点都被处理完时,说明所有的 节点都已排好序,或因图中存在循环而无法上完所有课程。

class Solution {
public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        vector<vector<int>> graph(numCourses, vector<int>());
        vector<int> indegree(numCourses, 0);
        vector<int> res;
        for(auto& prerequisite: prerequisites){
            graph[prerequisite[1]].push_back(prerequisite[0]);
            ++indegree[prerequisite[0]];
        }
        queue<int> q;
        for(int i=0; i<indegree.size(); ++i){
            if(indegree[i] == 0){
                q.push(i);
            }
        } 
        while(!q.empty()){
            int u = q.front();
            q.pop();
            res.push_back(u);
            for(auto& v: graph[u]){
                --indegree[v];;
                if(indegree[v] == 0){
                    q.push(v);
                }
            }
        }
        for(int i=0; i<indegree.size(); ++i){
            if(indegree[i]){
                return vector<int>();
            }
        }
        return res;
    }
};

三、巩固练习


欢迎大家共同学习和纠正指教

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Golang入门笔记(15)—— 数组和切片

编程的世界中&#xff0c;或许是因为一次一次的定义变量&#xff0c;维护管理起来都太费劲了&#xff0c;所以推出了数组&#xff0c;将数据用数组的形式管理起来。 Go的数组和Java的实现机制是不同的&#xff0c;Go语言的数组是作为基本数据类型存在的。所以数组是开辟在栈帧中…

Golang Web开发一键生成各层级模板代码

文章目录go_project_quickstart快速开始要求安装项目实现架构设计代码逻辑统一的调用逻辑代码复用每次写web项目&#xff0c;模板都是统一的&#xff0c;每次都要写大量冗余的代码会很烦&#xff0c;在Java中有很多逆向生成的工具&#xff0c;而Go语言我找了很久&#xff0c;也…

手把手搭建springboot项目,并测试springDataJPA

这篇文章记录了搭建springboot项目并测试springDataJPA的过程&#xff0c;接下来一起看看吧。 1.访问阿里云java脚手架网站 点击访问 2.按照下图勾选并获取代码 3.将获取到的代码解压到idea工作空间。 下图的JPAdemo就是我的项目 4.打开idea&#xff0c;导入项目 5.在pom…

【Redis】| 01 | Redis 可视化工具RedisInsight

目录1 RedisInsight 简介2 RedisInsight 安装2.1 安装2.1.1 软件安装2.1.1.1 下载 RedisInsight 软件包2.1.1.2 安装命令2.1.1.3 配置环境变量2.1.1.4 启动服务2.1.2 Kubernetes 安装2.1.2.1 创建 RedisInsight 的 yaml 文件2.1.2.2 启动3.RedisInsight 使用3.1 安装redis3.1.1…

Jacobi迭代的MPI进阶——计算通信重叠和虚拟进程的使用

1:条形分割的几种策略 这里先放Makefile和run.slurm Makefile CC = mpicc FLAGS = -O3 -Wall OBJ = *.o EXE = hang hangstartall Ihang xunihang qipan srqipan Isrqipan qipanendall: ${EXE}hang: hang.c $(CC) -o $@ $^ $(FLAGS)

信息安全结业复习题(选择 + 填空 + 简答 + 计算 + 设计 )含历年考题

这里写目录标题客观题知识点简答题计算题设计题客观题知识点 考过填空 密码学是保障信息安全的核心、信息安全是密码学研究和发展的目标 保证数字信息机密性的最有效方法是使用密码算法对其进行加密&#xff08;对称和非对称&#xff09; 保证信息完整性的有效方法是利用hash…

SQL Server全套教程(基于SQL语句----续更中)

SQL Server全套教程全程干货1. 数据库的基础操作1.1.0 创建数据库1.1.1 查看及修改数据库1.1.3 分离、附加和删除数据库2.数据库表的相关操作2.1.0 常用数据类型2.1.1 表结构的创建2.1.2 表结构的查看及修改1. 数据库的基础操作 1.1.0 创建数据库 数据库创建语法 -- 创建数据…

MicroPython-On-ESP8266——8x8LED点阵模块(2)使用74HC595驱动

MicroPython-On-ESP8266——8x8LED点阵模块&#xff08;2&#xff09;使用74HC595驱动 1. 使用74HC595驱动的原理 1.1. 基础回顾 上篇我们学习了8x8LED点阵屏的电路基础知识和驱动的原理&#xff0c;见 8x8LED点阵模块&#xff08;1&#xff09;驱动原理 里面也提到了&…

基于ssm+Javaweb的OA小型企业资源管理系统-计算机毕业设计

小型OA企业资源管理系统基于SSM(SpringSpringMVCMyBatis)框架,适用于毕业设计&#xff0c;采用javaweb,基于B/S模式,Myeclipse或者eclipse idea为开发工具,mysql数据库,主要包括登录模块、人事管理模块、公告管理模块、产品管理模块、和退出模块等多个模块。 本系统主要包含了…

MySQL高级篇知识点——主从复制

目录1.主从复制概述1.1.如何提升数据库并发能力1.2.主从复制的作用2.主从复制的原理2.1.原理剖析2.2.复制的基本原则3.一主一从架构搭建3.1.准备工作3.2.主机配置文件3.3.从机配置文件3.4.主机&#xff1a;建立账户并授权3.5.从机&#xff1a;配置需要复制的主机3.6.测试3.7.停…

tensorflow2.x --------------------DenseNet-----------------------------

用tensorflow2.4实现了DenseNet-121,训练基于ImageNet图像数据集&#xff0c;图片输入大小为 224x224 。网络结构采用包含4个DenseBlock的DenseNet-BC&#xff0c;每个DenseNet-BC由若干个 BNReLU1x1 ConvBNReLU3x3 Conv&#xff08;Dense_layer)且每个DenseBlock的特征图大小分…

听我劝,自学游戏建模真的很难

我的个人建议一直是偏向不要自学建模的&#xff08;特别是零基础&#x1f923;&#xff09;&#xff0c;学习3D游戏建模除了单纯需要为爱发电还需要能够自行✅掌握软件操作技巧和✅纠错改正&#xff0c;后者都是自学非常❌难做到的&#x1f62d; 除此之外&#xff0c;还有以下…

详解Unity中的Nav Mesh新特性|导航寻路系统 (二)

前言 第一篇我们简要概述了新版NavMesh的一些新增功能&#xff0c;以及旧版的对比。本篇我们来讲一讲NavMeshSurface、NavMeshLink这两个组件的参数以及如何应用&#xff0c;接下来就进入正题吧。 本系列提要 Unity新版NavMesh专题博客共分成三篇来讲解&#xff1a; 【本篇为…

Golang入门笔记(最后一章 17 封版)—— 映射map

映射 (map) 作为一个常用的类型&#xff0c;Go语言已为我们开发者内置了map类型。 基本语法&#xff1a; var 变量名 map [keyT类型] valueT类型 这里T就是一个类型代表&#xff08;我这么写&#xff0c;有点受到了Java的泛型影响&#xff09;&#xff0c;key的类型通常为str…

【20-业务开发-基础业务-商品模块-分类管理-前端展示后端具有层级关系的目录数据-商品系统三级分类的逻辑删除前后端代码实现】

一.知识回顾 【0.三高商城系统的专题专栏都帮你整理好了&#xff0c;请点击这里&#xff01;】 【1-系统架构演进过程】 【2-微服务系统架构需求】 【3-高性能、高并发、高可用的三高商城系统项目介绍】 【4-Linux云服务器上安装Docker】 【5-Docker安装部署MySQL和Redis服务】…

JUC线程池——newSingleThreadExecutor源码解析JDK提供线程池ThreadPoolExecutor执行任务流程解析

newSingleThreadExecutor源码解析&&JDK提供线程池ThreadPoolExecutor执行任务流程解析测试代码核心代码解析ThreadPoolExecutor内部类&#xff1a;Worker解析调试台线程切换到执行异步任务的线程ThreadPoolExecutor&#xff1a;getTask()LinkedBlockingQueue&#xff1…

shell-函数

函数介绍 shell中有系统函数&#xff0c;也可以自定义函数 系统函数 basename basename [pathname] [suffix] 返回完整路径最后的/的部分&#xff0c;常用于获取文件名 basename命令会删掉所有的前缀包括最后一个/字符&#xff0c;然后将字符串显示出来 suffix为后缀&#…

java计算机毕业设计专业招聘网站(附源码、数据库)

java计算机毕业设计专业招聘网站&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技…

从零搭建个人博客项目并通过github部署上线

文章目录一、环境准备二、创建hexo博客项目1.全局安装hexo-cil工具2.新建hexo项目3.启动项目三、部署上线1.新建github仓库2.修改配置项3.部署项目一、环境准备 1.Node.js (版本需不低于 10.13) 2.Git https://hexo.io/zh-cn/ hexo博客官方文档 二、创建hexo博客项目 1.全局安…

dhtmlx甘特图marker不随小时移动

dhtmlx甘特图marker是什么&#xff1f; 就是一个跟着日期变化的标记&#xff0c;如下图所示 这段代码是用来调整标记的样式&#xff0c;展示文本的关键代码&#xff0c;如要配置今日标记&#xff0c;需在plugins添加maker后加上这段代码 start_date是用来获得日期的&#xf…