【LeetCode】力扣刷题热题100道(31-35题)附源码 搜索二维矩阵 岛屿数量 腐烂的橙子 课程表 实现 Trie (前缀树)(C++)
一、搜索二维矩阵
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。


可以使用 从右上角开始搜索 的方法来有效地找到目标值。
- 选择起始位置: 从矩阵的右上角开始。假设我们当前的位置是
matrix[0][n-1],其中n是列数。 - 逐步搜索:
- 如果当前元素等于目标值,返回
true。 - 如果当前元素大于目标值,说明目标值可能出现在当前元素的左边,因此我们向左移动一列。
- 如果当前元素小于目标值,说明目标值可能出现在当前元素的下方,因此我们向下移动一行。
- 如果当前元素等于目标值,返回
- 结束条件: 如果超出了矩阵的边界,说明没有找到目标值,返回
false。
class Solution {
public:bool searchMatrix(vector<vector<int>>& matrix, int target) {if (matrix.empty() || matrix[0].empty()) return false;int m = matrix.size(); // 行数int n = matrix[0].size(); // 列数// 从右上角开始int row = 0;int col = n - 1;while (row < m && col >= 0) {if (matrix[row][col] == target) {return true; // 找到目标值} else if (matrix[row][col] > target) {col--; // 当前元素大于目标值,向左移动} else {row++; // 当前元素小于目标值,向下移动}}return false; // 没有找到目标值}
};
- 初始位置:从矩阵的右上角
matrix[0][n-1]开始。 - 移动规则:
- 如果当前元素等于目标值,则返回
true。 - 如果当前元素大于目标值,则移动到左边一列。
- 如果当前元素小于目标值,则移动到下方一行。
- 如果当前元素等于目标值,则返回
- 边界条件:当行数或列数超出范围时,结束搜索。
二、岛屿数量
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。

-
DFS 遍历:从每个尚未访问的陆地单元格开始,使用 DFS 遍历其所有相邻的陆地单元格,将它们标记为已访问。每次发现一个新的未被访问的陆地,就说明发现了一个新的岛屿。
-
标记访问:为了避免重复计算同一个岛屿,需要在遍历过程中将已经访问过的陆地标记为水('0'),这样就不会再次访问到它。
-
岛屿计数:每当我们从一个未访问的陆地开始 DFS 时,岛屿数加一。
- 对于每一个格子,如果它是陆地 ('1') 且未被访问,则从该格子开始进行 DFS,将与之相连的所有陆地格子标记为已访问,并将岛屿数量加一。
- 遍历所有格子,最终得到岛屿的数量。
- 对于一个陆地格子('1'),递归地向上下左右四个方向扩展,找到与它相连的所有陆地并将其标记为水('0')。
- 这样做的目的是确保每个岛屿的陆地只被计数一次。
class Solution {
public:void dfs(vector<vector<char>>& grid, int i, int j) {// 边界条件:如果当前格子越界或已经是水('0'),则返回if (i < 0 || i >= grid.size() || j < 0 || j >= grid[0].size() || grid[i][j] == '0') {return;}// 将当前陆地格子标记为水,表示已访问grid[i][j] = '0';// 递归四个方向dfs(grid, i + 1, j); // 向下dfs(grid, i - 1, j); // 向上dfs(grid, i, j + 1); // 向右dfs(grid, i, j - 1); // 向左}int numIslands(vector<vector<char>>& grid) {if (grid.empty()) return 0;int numIslands = 0;// 遍历整个网格for (int i = 0; i < grid.size(); ++i) {for (int j = 0; j < grid[0].size(); ++j) {// 找到一个未访问的陆地,启动 DFSif (grid[i][j] == '1') {numIslands++; // 发现新的岛屿dfs(grid, i, j); // 使用 DFS 标记整个岛屿}}}return numIslands;}
};
-
DFS 函数:
dfs用来递归访问与当前格子相连的所有陆地格子,并将它们标记为水('0')。- 参数
i, j表示当前正在处理的格子坐标。 - 在函数内部,首先检查是否越界或是否已经是水('0'),如果是则直接返回。
- 然后标记当前格子为水,并递归检查四个方向(上下左右)。
- 参数
-
主函数:
numIslands遍历整个二维网格,发现每个未访问的陆地时,调用dfs来标记所有相连的陆地,从而确保每个岛屿只计算一次。 -
边界条件:如果网格为空,直接返回
0。
三、腐烂的橙子
在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:
- 值
0代表空单元格; - 值
1代表新鲜橘子; - 值
2代表腐烂的橘子。
每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。

class Solution {
public:int orangesRotting(vector<vector<int>>& grid) {int m = grid.size();int n = grid[0].size();// 记录腐烂的橘子的位置queue<pair<int, int>> rotten;int freshCount = 0; // 记录新鲜橘子的数量// 初始化队列和新鲜橘子数量for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (grid[i][j] == 2) {rotten.push({i, j});} else if (grid[i][j] == 1) {freshCount++;}}}// 如果没有新鲜橘子,直接返回 0if (freshCount == 0) return 0;// 四个方向vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};int minutes = 0;// 开始 BFSwhile (!rotten.empty()) {int size = rotten.size();bool rottedThisRound = false; // 记录这一轮是否有橘子腐烂for (int i = 0; i < size; ++i) {auto [x, y] = rotten.front();rotten.pop();// 四个方向扩展for (auto& dir : directions) {int nx = x + dir.first;int ny = y + dir.second;// 如果新位置在网格内且是新鲜橘子if (nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] == 1) {grid[nx][ny] = 2; // 将新鲜橘子腐烂rotten.push({nx, ny}); // 加入队列freshCount--; // 减少新鲜橘子的数量rottedThisRound = true;}}}// 如果这一轮有橘子腐烂,时间增加if (rottedThisRound) {minutes++;}}// 如果还有新鲜橘子,返回 -1return freshCount == 0 ? minutes : -1;}
};
- 初始化:
- 我们先遍历网格,找到所有腐烂的橘子,并将其加入队列。同时,我们统计新鲜橘子的数量。
- BFS 过程:
- 我们从腐烂的橘子开始,逐层扩展,检查每个腐烂橘子周围的四个方向。
- 如果发现相邻位置是新鲜橘子(值为
1),我们就把它变成腐烂的橘子(值改为2),并将其加入队列,继续扩展。 - 每次扩展都意味着时间增加一分钟。
- 结束条件:
- 如果在 BFS 完成后还有新鲜橘子(
freshCount > 0),说明不能完全腐烂所有橘子,返回-1。 - 否则,返回所需的分钟数。
- 如果在 BFS 完成后还有新鲜橘子(
四、课程表
你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。
- 例如,先修课程对
[0, 1]表示:想要学习课程0,你需要先完成课程1。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。

class Solution {
public:bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {vector<int> indegree(numCourses, 0); // 记录每个课程的入度vector<vector<int>> graph(numCourses); // 邻接表表示图// 构建图和入度数组for (const auto& prereq : prerequisites) {int course = prereq[0]; // 需要学习的课程int pre = prereq[1]; // 先修课程graph[pre].push_back(course); // 将 course 加入 pre 的邻接表indegree[course]++; // course 的入度加 1}// 使用队列存储入度为 0 的课程queue<int> q;for (int i = 0; i < numCourses; ++i) {if (indegree[i] == 0) {q.push(i); // 将入度为 0 的课程加入队列}}int count = 0; // 记录已修课程的数量while (!q.empty()) {int course = q.front();q.pop();count++;// 对当前课程的所有后续课程(即它的邻接课程)进行处理for (int nextCourse : graph[course]) {indegree[nextCourse]--; // 当前课程修完,减去下一个课程的入度if (indegree[nextCourse] == 0) {q.push(nextCourse); // 如果下一个课程的入度为 0,加入队列}}}// 如果修完的课程数量等于总课程数,则可以完成所有课程return count == numCourses;}
};
- 构建图和入度数组:
- 我们首先创建一个
graph数组来存储图的邻接表,并创建一个indegree数组来记录每个课程的入度(即每个课程有多少先修课程)。 - 然后,我们根据
prerequisites数组来构建图,并更新每个课程的入度。
- 我们首先创建一个
- 拓扑排序:
- 我们初始化一个队列
q,将所有入度为 0 的课程加入队列。 - 逐个从队列中取出课程,修完后,将它的邻接课程的入度减 1。如果某个邻接课程的入度变为 0,则将它加入队列。
- 我们初始化一个队列
- 判断是否完成所有课程:
- 最后,我们检查已修的课程数量
count是否等于总课程数numCourses。如果相等,说明没有环路,返回true;否则,返回false。
- 最后,我们检查已修的课程数量
五、实现 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 Trie {
private:struct TrieNode {unordered_map<char, TrieNode*> children;bool isWord;TrieNode() : isWord(false) {}};TrieNode* root;public:// 构造函数,初始化 Trie 树Trie() {root = new TrieNode();}// 向 Trie 插入一个字符串void insert(string word) {TrieNode* node = root;for (char c : word) {// 如果当前字符的子节点不存在,则创建一个新的节点if (node->children.find(c) == node->children.end()) {node->children[c] = new TrieNode();}node = node->children[c];}// 标记字符串结束的节点node->isWord = true;}// 查找字符串是否存在于 Trie 中bool search(string word) {TrieNode* node = root;for (char c : word) {if (node->children.find(c) == node->children.end()) {return false; // 如果有字符没有找到对应节点,返回 false}node = node->children[c];}// 如果到达字符串结尾并且是一个完整的单词,返回 truereturn node->isWord;}// 检查是否有任何单词以 prefix 为前缀bool startsWith(string prefix) {TrieNode* node = root;for (char c : prefix) {if (node->children.find(c) == node->children.end()) {return false; // 如果有字符没有找到对应节点,返回 false}node = node->children[c];}// 如果遍历完整个前缀,说明 Trie 中有以 prefix 为前缀的单词return true;}
};/*** Your Trie object will be instantiated and called as such:* Trie* obj = new Trie();* obj->insert(word);* bool param_2 = obj->search(word);* bool param_3 = obj->startsWith(prefix);*/
-
TrieNode 结构体:每个
TrieNode代表一个树节点,包含:children:一个哈希表,键是字符,值是指向子节点的指针。这个哈希表用于存储当前节点的所有子节点。isWord:一个布尔值,标记当前节点是否为一个单词的结束。
-
Trie 构造函数:创建一个空的根节点
root。 -
insert(word):
- 从根节点开始,逐个字符遍历
word。 - 如果某个字符的子节点不存在,则创建一个新的子节点。
- 最后,将最后一个字符的
isWord标记为true,表示这是一个完整的单词。
- 从根节点开始,逐个字符遍历
-
search(word):
- 从根节点开始,逐个字符遍历
word。 - 如果在任何字符位置找不到对应的子节点,则返回
false。 - 如果遍历结束并且当前节点的
isWord为true,说明找到了该单词,返回true。
- 从根节点开始,逐个字符遍历
-
startsWith(prefix):
- 从根节点开始,逐个字符遍历
prefix。 - 如果在某个字符位置找不到对应的子节点,则返回
false。 - 如果能够遍历完前缀的所有字符,说明存在以该前缀为开始的单词,返回
true。
- 从根节点开始,逐个字符遍历
相关文章:
【LeetCode】力扣刷题热题100道(31-35题)附源码 搜索二维矩阵 岛屿数量 腐烂的橙子 课程表 实现 Trie (前缀树)(C++)
一、搜索二维矩阵 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 可以使用 从右上角开始搜索 的方法来有效地找到目标值。 选择起始位置: 从矩…...
react使用react-redux状态管理
1、安装 npm install react-redux2、创建store.js import { createStore } from redux;// 定义初始状态 const initialState {counter: 888 };// 定义 reducer 函数,根据 action 类型更新状态 function reducer(state initialState, action) {switch (action.ty…...
04_角色创建窗口
将上文的登录窗口隐藏 创建空节点 作为创建角色窗口 命名为CreateWnd 创建输入的名字的输入框 再创建一个按钮用来随机角色名字 创建开始游戏按钮 End....
Dockerfile -> Docker image -> Docker container
1. Dockfile -> Docker image docker build -t shuai_image -f xxx/xxx/Dockerfile . (.不能少)出现: [] Building xxx(10/17) > [internal] load build definition from Dockerfile > > transferring dockerfile: … > > transferring context …...
LDN的蓝牙双模键盘帮助文档
文档索引 已支持的PCB列表(仅列出少部分):键盘特性硬件软件键盘以及驱动蓝牙模式USB模式 驱动功能介绍主界面键盘列表页面键盘配置(使用双模键盘的请务必细看本说明)功能层配置(改键)触发层配置(改FN键等触发功能)功能选择(重要&a…...
搭建一个基于Spring Boot的驾校管理系统
搭建一个基于Spring Boot的驾校管理系统可以涵盖多个功能模块,例如学员管理、教练管理、课程管理、考试管理、车辆管理等。以下是一个简化的步骤指南,帮助你快速搭建一个基础的系统。 1. 项目初始化 使用 Spring Initializr 生成一个Spring Boot项目&am…...
运动相机拍视频过程中摔了,导致录视频打不开怎么办
3-11 在使用运动相机拍摄激烈运动的时候,极大的震动会有一定概率使得保存在存储卡中的视频出现打不开的情况,原因是存储卡和相机在极端情况下,可能会出现接触不良的问题,如果遇到这种问题,就不得不进行视频修复了。 本…...
MongoDB vs Redis:相似与区别
前言 在当今的数据库领域,MongoDB 和 Redis 都是备受关注的非关系型数据库(NoSQL),它们各自具有独特的优势和适用场景。本文将深入探讨 MongoDB 和 Redis 的特点,并详细对比它们之间的相似之处和区别,帮助…...
数字图像处理:实验二
任务一: 将不同像素(32、64和256)的原图像放大为像素大 小为1024*1024的图像(图像自选) 要求:1)输出一幅图,该图包含六幅子图,第一排是原图,第 二排是对应放大…...
基于海思soc的智能产品开发(高、中、低soc、以及和fpga的搭配)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 市场上关于图像、音频的soc其实非常多,这里面有高、中、低档,开发方式也不相同。之所以会这样,有价格的因素&am…...
SSM旅游信息管理系统
🍅点赞收藏关注 → 添加文档最下方联系方式可咨询本源代码、数据库🍅 本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目希望你能有所收获,少走一些弯路。🍅关注我不迷路🍅 项目视频 …...
FastADMIN实现网站启动时执行程序的方法
FastAdmin基于ThinkPHP框架:ThinkPHP框架中与 Application_Start 类似的功能可以在应用初始化钩子(Hook)中实现。在FastAdmin项目中,一般在应用的 common.php 文件中定义行为(Behavior)来实现类似功能。 定…...
【威联通】FTP服务提示:服务器回应不可路由的地址。被动模式失败。
FTP服务器提示:服务器回应不可路由的地址。被动模式失败。 问题原因网络结构安全管理配置服务器配置网关 问题 FTP服务器提示:服务器回应不可路由的地址…...
nginx常用配置 (含负载均衡、反向代理、限流、Gzip压缩、图片防盗链 等示例)
nginx的配置文件通常在 /etc/nginx/nginx.conf , /etc/nginx/conf.d/*.conf 中, 一般直接 改 conf.d目录下的 default.conf文件, 然后 先检测配置文件是否有错误 nginx -t 再重新加载配置文件 或 重启nginx,命令如下 nginx -s reload 或…...
21.1、网络设备安全概述
目录 网络设备安全概况——交换机、路由器安全威胁 网络设备安全概况——交换机、路由器安全威胁 第一个是MAC地址泛洪,MAC地址表记录着交换机拥有的MAC地址跟端口的对应关系 MAC地址表主要是三个字段,MAC地址对应的端口号,也就表示主机是连…...
通过idea创建的springmvc工程需要的配置
在创建的spring mvc工程中,使用idea开发之前需要配置文件包括porm.xml、web.xml、springmvc.xml 1、porm.xml 工程以来的spring库,主要包括spring-aop、spring-web、spring-webmvc,示例配置如下: <project xmlns"http:/…...
Redis 持久化机制:RDB 和 AOF
Redis 持久化机制:RDB 和 AOF Redis 主要提供了两种持久化方式:**RDB(Redis Database)**和 AOF(Append-Only File)。它们各自的实现原理、优缺点以及适用场景如下。 1. RDB(Redis Database&…...
【博客之星评选】2024年度前端学习总结
故事的开端...始于2024年第一篇前端技术博客 那故事的终末...也该结束于陪伴了我一整年的前端知识了 踏入 2025 年,满心激动与自豪,我成功闯进了《2024 年度 CSDN 博客之星总评选》的 TOP300。作为一名刚接触技术写作不久的萌新,这次能走到这…...
将IDLE里面python环境pyqt5配置的vscode
首先安装pyqt5全套:pip install pyqt5-tools 打开Vscode: 安装第三方扩展:PYQT Integration 成功配置designer.exe的路径【个人安装pyqt5的执行路径】,便可直接打开UI文件,进行编辑。 配置pyuic,如果下图填写方法使用…...
【专题三:穷举vs暴搜vs深搜vs回溯vs剪枝】46. 全排列
1.题目解析 2.讲解算法原理 1.首先画出决策树,越详细越好 2.设计代码 全局变量 List<List<Integer>> retList<Integer> pathboolean[] check dfs函数 仅关心某一节点在干什么 细节问题回溯 干掉path最后一个元素修改check权限 剪枝 check中为…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
