力扣top100(day03-02)--图论

 本文为力扣TOP100刷题笔记

笔者根据数据结构理论加上最近刷题整理了一套 数据结构理论加常用方法以下为该文章:

力扣外传之数据结构(一篇文章搞定数据结构)

200. 岛屿数量

class Solution {// DFS辅助方法,用于标记和"淹没"岛屿void dfs(char[][] grid, int r, int c) {int nr = grid.length;    // 网格行数int nc = grid[0].length; // 网格列数// 边界检查及是否陆地的检查if (r < 0 || c < 0 || r >= nr || c >= nc || grid[r][c] == '0') {return;}// 将当前陆地标记为已访问('0'表示水或已访问)grid[r][c] = '0';// 向四个方向递归搜索dfs(grid, r - 1, c); // 上dfs(grid, r + 1, c); // 下dfs(grid, r, c - 1); // 左dfs(grid, r, c + 1); // 右}public int numIslands(char[][] grid) {// 处理空网格的情况if (grid == null || grid.length == 0) {return 0;}int nr = grid.length;    // 网格行数int nc = grid[0].length; // 网格列数int num_islands = 0;     // 岛屿计数器// 遍历整个网格for (int r = 0; r < nr; ++r) {for (int c = 0; c < nc; ++c) {// 发现新岛屿if (grid[r][c] == '1') {++num_islands;    // 增加岛屿计数dfs(grid, r, c);  // "淹没"整个岛屿}}}return num_islands;}
}

关键点解释

  1. DFS标记过程

    • 将访问到的'1'标记为'0',避免重复计数

    • 向四个方向(上、下、左、右)递归搜索相连的陆地

  2. 岛屿计数逻辑

    • 每次遇到未被访问的'1',表示发现新岛屿

    • 调用DFS"淹没"整个岛屿,确保不会重复计数

  3. 边界条件处理

    • 检查网格坐标是否越界

    • 处理空网格输入的情况

示例演示

给定网格:

text

1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

执行过程:

  1. 发现(0,0)的'1',计数+1,DFS淹没左上角2×2岛屿

  2. 跳过已访问/水区域

  3. 发现(2,2)的'1',计数+1,DFS淹没该孤立点

  4. 发现(3,3)的'1',计数+1,DFS淹没右下角2×1岛屿

  5. 最终岛屿数量:3

994. 腐烂的橘子

class Solution {public int orangesRotting(int[][] grid) {if (grid == null || grid.length == 0) return -1;int rows = grid.length;int cols = grid[0].length;int minutes = 0;while (true) {boolean changed = false;int[][] newGrid = new int[rows][cols];// 复制当前网格状态for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {newGrid[i][j] = grid[i][j];}}// 递归处理每个橘子for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {if (grid[i][j] == 2) {changed |= infectAdjacent(grid, newGrid, i, j, rows, cols);}}}// 如果没有变化,退出循环if (!changed) break;// 更新网格并增加分钟数grid = newGrid;minutes++;}// 检查是否还有新鲜橘子for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {if (grid[i][j] == 1) return -1;}}return minutes;}// 递归感染相邻橘子的辅助方法private boolean infectAdjacent(int[][] grid, int[][] newGrid, int i, int j, int rows, int cols) {boolean changed = false;int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};for (int[] dir : directions) {int x = i + dir[0];int y = j + dir[1];if (x >= 0 && y >= 0 && x < rows && y < cols && grid[x][y] == 1) {newGrid[x][y] = 2;changed = true;}}return changed;}
}

递归思路解析

  1. 外层循环:每分钟处理一次腐烂过程

  2. 网格复制:创建新网格来记录下一分钟的状态

  3. 递归处理

    • 遍历每个腐烂橘子(值为2)

    • 使用infectAdjacent方法递归感染相邻的新鲜橘子

  4. 终止条件

    • 当没有更多橘子可以被感染时退出循环

    • 最后检查是否还有剩余的新鲜橘子

为什么这不是纯递归

实际上,这个问题不太适合纯递归解决,因为:

  1. 多源点问题:多个腐烂橘子需要同时扩散

  2. 时间步长:需要按分钟同步处理所有腐烂

上面的解决方案使用了递归辅助方法,但整体结构仍然是迭代的(每分钟处理一次)。

纯递归的局限性

如果非要实现纯递归版本,会遇到以下问题:

  1. 难以同步时间:所有腐烂过程无法同步进行

  2. 重复计算:同一个橘子可能被多次处理

  3. 栈溢出风险:对于大网格会超出调用栈深度

207. 课程表

class Solution {// 邻接表,存储图的边关系,edges.get(i)表示课程i的所有后续课程List<List<Integer>> edges;// 记录每个节点的访问状态:0=未访问,1=访问中,2=已访问完成int[] visited;// 全局标志,表示当前是否没有发现环(能否完成所有课程)boolean valid = true;public boolean canFinish(int numCourses, int[][] prerequisites) {// 初始化邻接表edges = new ArrayList<List<Integer>>();for (int i = 0; i < numCourses; ++i) {edges.add(new ArrayList<Integer>());}// 初始化访问状态数组visited = new int[numCourses];// 构建图的边关系// prerequisites中的每个元素[1,0]表示要学习课程1必须先完成课程0// 所以在邻接表中,我们添加边 0→1for (int[] info : prerequisites) {edges.get(info[1]).add(info[0]);}// 对每个未访问的节点执行DFSfor (int i = 0; i < numCourses && valid; ++i) {if (visited[i] == 0) {dfs(i);}}// 如果整个过程中没有发现环,则可以完成所有课程return valid;}public void dfs(int u) {// 标记当前节点为"访问中"visited[u] = 1;// 遍历当前节点的所有邻接节点(后续课程)for (int v: edges.get(u)) {// 如果邻接节点未被访问,递归访问if (visited[v] == 0) {dfs(v);// 如果在递归过程中发现环,提前返回if (!valid) {return;}} // 如果邻接节点正在访问中(在递归栈中),说明发现环else if (visited[v] == 1) {valid = false;return;}// 如果邻接节点已访问完成(2),不需要处理}// 当前节点访问完成,标记为"已访问"visited[u] = 2;}
}

关键注释说明

  1. 邻接表edges

    • 使用ArrayList的ArrayList实现

    • edges.get(i)获取课程i的所有直接后续课程列表

  2. visited数组三种状态

    • 0:白色,未访问节点

    • 1:灰色,正在访问中的节点(在递归栈中)

    • 2:黑色,已完全访问完成的节点

  3. 环检测逻辑

    • 在DFS过程中,如果遇到灰色节点(状态1),说明存在环

    • 因为灰色节点表示该节点在当前的递归调用栈中,再次遇到说明形成了环

  4. DFS过程

    • 先将节点标记为灰色(访问中)

    • 递归访问所有邻接节点

    • 最后将节点标记为黑色(访问完成)

  5. 提前终止

    • 一旦发现环(valid=false),立即终止后续的DFS过程

这个算法有效地利用DFS实现了有向无环图(DAG)的检测,解决了课程安排问题。

208. 实现 Trie (前缀树)

class Trie {// 每个Trie节点包含:// 1. 一个长度为26的子节点数组(对应26个小写字母)// 2. 一个布尔值标记是否是某个单词的结尾private Trie[] children;private boolean isEnd;// 构造函数:初始化一个空的Trie节点public Trie() {children = new Trie[26];  // 26个字母的子节点isEnd = false;           // 初始时不是单词结尾}// 向Trie中插入一个单词public void insert(String word) {Trie node = this;  // 从根节点开始for (int i = 0; i < word.length(); i++) {char ch = word.charAt(i);int index = ch - 'a';  // 计算字母对应的索引(0-25)// 如果当前字符对应的子节点不存在,则创建新的子节点if (node.children[index] == null) {node.children[index] = new Trie();}// 移动到子节点node = node.children[index];}// 标记单词的最后一个字符节点为结尾node.isEnd = true;}// 搜索Trie中是否存在完整的单词public boolean search(String word) {Trie node = searchPrefix(word);// 不仅要找到前缀,最后一个节点还必须标记为单词结尾return node != null && node.isEnd;}// 检查Trie中是否有以给定前缀开头的单词public boolean startsWith(String prefix) {// 只需要找到前缀路径存在即可return searchPrefix(prefix) != null;}// 私有辅助方法:搜索前缀private Trie searchPrefix(String prefix) {Trie node = this;  // 从根节点开始for (int i = 0; i < prefix.length(); i++) {char ch = prefix.charAt(i);int index = ch - 'a';  // 计算字母对应的索引(0-25)// 如果当前字符对应的子节点不存在,返回nullif (node.children[index] == null) {return null;}// 移动到子节点node = node.children[index];}// 返回前缀的最后一个字符节点return node;}
}

关键注释说明

  1. 数据结构设计

    • children数组:每个元素对应一个字母(a-z),存储指向子Trie节点的引用

    • isEnd标志:标记当前节点是否是某个单词的结尾

  2. 插入操作(insert)

    • 从根节点开始,逐个字符处理

    • 对于每个字符,检查对应的子节点是否存在,不存在则创建

    • 最后将单词的最后一个字符节点标记为结尾

  3. 搜索操作(search)

    • 使用searchPrefix方法找到前缀的最后一个节点

    • 检查该节点是否存在且被标记为单词结尾

  4. 前缀检查(startsWith)

    • 只需要检查前缀路径是否存在,不关心是否是完整单词

  5. 辅助方法(searchPrefix)

    • 通用的前缀查找方法

    • 被search和startsWith方法复用

    • 返回前缀路径的最后一个节点(如果存在)

时间复杂度分析

  • 插入:O(L),L为单词长度

  • 搜索:O(L),L为单词长度

  • 前缀检查:O(P),P为前缀长度

空间复杂度

  • 最坏情况:O(N×M),N是单词数量,M是平均单词长度

  • 实际中由于共享前缀,空间效率通常比哈希表更好

这个Trie实现特别适合处理字符串的前缀相关问题,如自动补全、拼写检查等场景。

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

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

相关文章

建造者模式:从“参数地狱”到优雅构建

深夜&#xff0c;一条紧急告警刺穿寂静&#xff1a;核心报表服务因NullPointerException全线崩溃。排查根源&#xff0c;罪魁祸首竟是一个拥有10多个参数的“上帝构造函数”。本文将从这个灾难现场出发&#xff0c;引入“链式建造者模式”进行重构&#xff0c;并深入Spring AI、…

jenkins在windows配置sshpass

我的服务器里jenkins是通过docker安装的&#xff0c;jenkins与项目都部署在同一台服务器上还好&#xff0c;但是当需要通过jenkins构建&#xff0c;再通过scp远程推送到别的服务器上&#xff0c;就出问题了&#xff0c;毕竟不是手动执行scp命令&#xff0c;可以手动输入密码&am…

Linux操作系统从入门到实战(十八)在Linux里面怎么查看进程

Linux操作系统从入门到实战&#xff08;十八&#xff09;在Linux里面怎么查看进程前言一、如何识别一个进程&#xff1f;—— PID二、怎么查看进程的信息&#xff1f;方式1&#xff1a;通过/proc目录方式2&#xff1a;用ps命令三、父进程是什么&#xff1f;—— PPID四、bash是…

[TryHackMe](知识学习)---基于堆栈得到缓冲区溢出

1.了解缓冲区溢出WINDOWS程序动态调试工具immunity debuggerhttps://www.immunityinc.com/products/debugger/2.Mona脚本#!/usr/bin/env python3import socket, time, sysip "10.201.99.37"port 1337 timeout 5 prefix "OVERFLOW1 "string prefix &q…

LRU算法与LFU算法

知识点&#xff1a; LRU是Least Recently Used的缩写&#xff0c;意思是最近最少使用&#xff0c;它是一种Cache替换算法 Cache的容量有限&#xff0c;因此当Cache的容量用完后&#xff0c;而又有新的内容需要添加进来时&#xff0c; 就需要挑选 并舍弃原有的部分内容&#xf…

目标检测公开数据集全解析:从经典到前沿

目标检测公开数据集全解析&#xff1a;从经典到前沿 一、引言 目标检测&#xff08;Object Detection&#xff09;是计算机视觉领域的核心任务之一&#xff0c;旨在在图像或视频中识别并定位感兴趣的物体。与图像分类不同&#xff0c;目标检测不仅需要判断物体的类别&#xf…

数据备份与进程管理

一、数据备份1.Linux服务器中需要备份的数据&#xff08;1&#xff09;Linux系统重要数据&#xff1a;/root/目录&#xff0c;/home/目录&#xff0c;/etc/目录&#xff08;2&#xff09;安装服务的数据&#xff1a;Apache&#xff08;配置文件&#xff0c;网页主目录&#xff…

docker volume卷入门教程

1. 基础概念 Docker卷是专门用于持久化容器数据的存储方案&#xff0c;独立于容器生命周期。其核心优势包括&#xff1a; 数据持久化&#xff1a;容器删除后数据仍保留跨容器共享&#xff1a;多个容器可访问同一卷备份与迁移&#xff1a;支持直接复制卷数据驱动支持&#xff1a…

计算机网络——协议

1. 计算机网络分层1.1 OSI 7层模型应用层表示层会话层传输层网络层数据链路层物理层1.2 TCP/IP 4 层模型应用层运输层网际层网络接口层1.3 5层体系机构应用层传输层网络层数据链路层物理层2. 应用层协议2.1 HTTP协议2.1.1 基本介绍HTTP&#xff08;HyperText Transfer Protocol…

【React】hooks 中的闭包陷阱

在 React Hooks 中的 闭包陷阱&#xff08;Closure Trap&#xff09;在 useEffect、事件回调、定时器等场景里很常见。1. 闭包陷阱是什么 当你在函数组件里定义一个回调&#xff08;比如事件处理函数&#xff09;&#xff0c;这个回调会捕获当时渲染时的变量值。如果后面状态更…

校园快递小程序(腾讯地图API、二维码识别、Echarts图形化分析)

&#x1f388;系统亮点&#xff1a;腾讯地图API、二维码识别、Echarts图形化分析&#xff1b;一.系统开发工具与环境搭建1.系统设计开发工具后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17小程序&#xff1a; 技术…

Python网络爬虫(二) - 解析静态网页

文章目录一、网页解析技术介绍二、Beautiful Soup库1. Beautiful Soup库介绍2. Beautiful Soup库几种解析器比较3. 安装Beautiful Soup库3.1 安装 Beautiful Soup 43.2 安装解析器4. Beautiful Soup使用步骤4.1 创建Beautiful Soup对象4.2 获取标签4.2.1 通过标签名获取4.2.2 通…

【Linux基础知识系列】第九十四篇 - 如何使用traceroute命令追踪路由

在网络环境中&#xff0c;了解数据包从源主机到目标主机的路径是非常重要的。这不仅可以帮助我们分析网络连接问题&#xff0c;还可以用于诊断网络延迟、丢包等问题。traceroute命令是一个强大的工具&#xff0c;它能够追踪数据包在网络中的路径&#xff0c;显示每一跳的延迟和…

达梦数据闪回查询-快速恢复表

Time:2025/08/12Author:skatexg一、环境说明DM数据库&#xff1a;DM8.0及以上版本二、适用场景研发在误操作或变更数据后&#xff0c;想马上恢复表到某个时间点&#xff0c;可以通过闪回查询功能快速实现&#xff08;通过全量备份恢复时间长&#xff0c;成本高&#xff09;三、…

力扣(LeetCode) ——225 用队列实现栈(C语言)

题目&#xff1a;用队列实现栈示例1&#xff1a; 输入&#xff1a; [“MyStack”, “push”, “push”, “top”, “pop”, “empty”] [[], [1], [2], [], [], []] 输出&#xff1a; [null, null, null, 2, 2, false] 解释&#xff1a; MyStack myStack new MyStack(); mySta…

微软推出AI恶意软件检测智能体 Project Ire

开篇 在8月5号&#xff0c;微软研究院发布了一篇博客文章&#xff0c;在该篇博客中推出了一款名为Project Ire的AI Agent。该Agent可以在无需人类协助的情况下&#xff0c;自主分析和分类二进制文件。它可以在无需了解二进制文件来源或用途的情况下&#xff0c;对文件进行完全的…

哪些对会交由SpringBoot容器管理?

在 Spring Boot 中,交由容器管理的对象通常称为“Spring Bean”,这些对象的创建、依赖注入、生命周期等由 Spring 容器统一管控。以下是常见的会被 Spring Boot 容器管理的对象类型及识别方式: 一、通过注解声明的组件(最常见) Spring Boot 通过类级别的注解自动扫描并注…

Android POS应用在android运行常见问题及解决方案

概述 本文档记录了在Android POS应用开发过程中遇到的两个关键问题及其解决方案&#xff1a; UnsatisfiedLinkError: couldnt find "libnative.so" 错误ActivityNotFoundException 错误商户信息一致性检查绕过 问题1&#xff1a;UnsatisfiedLinkError - libnative.so…

基于SpringBoot的旅游网站系统

1. 项目简介 旅游线路管理系统是一个基于Spring Boot的在线旅游服务平台&#xff0c;提供旅游线路展示、分类、预订、订单管理等功能。系统包含前台用户界面和后台管理模块&#xff0c;支持用户注册登录、线路浏览、收藏、下单支付、客服咨询等核心功能。管理员可管理线路信息、…

CVPR 2025 | 机器人操控 | RoboGround:用“掩码”中介表示,让机器人跨场景泛化更聪明

点击关注gongzhonghao【计算机sci论文精选】1.导读1.1论文基本信息论文标题&#xff1a;ROBOGROUND: Robotic Manipulation with Grounded Vision-Language Priors作者&#xff1a;Haifeng Huang, Xinyi Chen, Hao Li&#xff0c; Xiaoshen Han, Yilun Chen, Tai Wang, Zehan W…