面试经典150题——图
文章目录
- 1、岛屿数量
- 1.1 题目链接
- 1.2 题目描述
- 1.3 解题代码
- 1.4 解题思路
- 2、被围绕的区域
- 2.1 题目链接
- 2.2 题目描述
- 2.3 解题代码
- 2.4 解题思路
- 3、克隆图
- 3.1 题目链接
- 3.2 题目描述
- 3.3 解题代码
- 3.4 解题思路
- 4、除法求值
- 4.1 题目链接
- 4.2 题目描述
- 4.3 解题代码
- 4.4 解题思路
- 5、课程表
- 5.1 题目链接
- 5.2 题目描述
- 5.3 解题代码
- 5.4 解题思路
- 6、课程表 II
- 6.1 题目链接
- 6.2 题目描述
- 6.3 解题代码
- 6.4 解题思路
1、岛屿数量
1.1 题目链接
点击跳转到题目位置
1.2 题目描述
给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
提示:
- m == grid.length
- n == grid[i].length
- 1 <= m, n <= 300
- grid[i][j] 的值为 ‘0’ 或 ‘1’
1.3 解题代码
class Solution {int[][] dir = {{-1, 0},{1, 0},{0, 1},{0, -1},};public int numIslands(char[][] grid) {Map<Integer, Integer> hash = new HashMap<Integer, Integer>(); int m = grid.length;int n = grid[0].length;int ret = 0;Queue<Integer> q = new LinkedList();for(int i = 0; i < m; ++i){for(int j = 0; j < n; ++j){if(grid[i][j] == '1' && !hash.containsKey(500 * i + j)){q.offer(500 * i + j);hash.put(500 * i + j, 1);++ret;}while(!q.isEmpty()){int num = q.peek();q.poll();int x = num / 500;int y = num % 500;for(int k = 0; k < 4; ++k){int tx = x + dir[k][0];int ty = y + dir[k][1];if(tx < 0 || tx >= m || ty < 0 || ty >= n || grid[tx][ty] == '0'){continue;}if(!hash.containsKey(tx * 500 + ty)){hash.put(tx * 500 + ty, 1);q.offer(tx * 500 + ty);}}}}}return ret;}
}
1.4 解题思路
- 使用广度优先搜索来解决问题。
- 广度优先搜索的核心思路为哈希+队列。
2、被围绕的区域
2.1 题目链接
点击跳转到题目位置
2.2 题目描述
给你一个 m x n 的矩阵 board ,由若干字符 ‘X’ 和 ‘O’ 组成,捕获 所有 被围绕的区域:
- **连接:**一个单元格与水平或垂直方向上相邻的单元格连接。
- 区域:连接所有 ‘O’ 的单元格来形成一个区域。
- **围绕:**如果您可以用 ‘X’ 单元格 连接这个区域,并且区域中没有任何单元格位于 board 边缘,则该区域被 ‘X’ 单元格围绕。
通过 原地 将输入矩阵中的所有 ‘O’ 替换为 ‘X’ 来 捕获被围绕的区域。你不需要返回任何值。
提示:
- m == board.length
- n == board[i].length
- 1 <= m, n <= 200
- board[i][j] 为 ‘X’ 或 ‘O’
2.3 解题代码
class Solution {int[][] dir = {{-1, 0},{1, 0},{0, -1},{0, 1},};Map<Integer, Integer> hash = new HashMap<Integer, Integer>();void bfs(char[][] board, int startX, int startY, int m, int n){Queue<Integer> q = new LinkedList();q.offer(startX * 500 + startY);hash.put(startX * 500 + startY, 1);while(!q.isEmpty()){int num = q.peek();q.poll();int x = num / 500;int y = num % 500;for(int k = 0; k < 4; ++k){int tx = x + dir[k][0];int ty = y + dir[k][1];if(tx < 0 || tx >= m || ty < 0 || ty >= n || board[tx][ty] == 'X'){continue;}if(!hash.containsKey(tx * 500 + ty)){hash.put(tx * 500 + ty, 1);q.offer(tx * 500 + ty);}}}}public void solve(char[][] board) {int m = board.length;int n = board[0].length;for(int i = 0; i < m; ++i){if(board[i][0] == 'O' && !hash.containsKey(i * 500 + 0)){bfs(board, i, 0, m, n);}if(board[i][n - 1] == 'O' && !hash.containsKey(i * 500 + n - 1)){bfs(board, i, n - 1, m, n);}}for(int j = 0; j < n; ++j){if(board[0][j] == 'O' && !hash.containsKey(0 * 500 + j)){bfs(board, 0, j, m, n);}if(board[m - 1][j] == 'O' && !hash.containsKey((m - 1) * 500 + j)){bfs(board, m - 1, j, m, n);}}for(int i = 0; i < m; ++i){for(int j = 0; j < n; ++j){if(board[i][j] == 'O' && !hash.containsKey(i * 500 + j)){board[i][j] = 'X';}}}}
}
2.4 解题思路
- 广度优先搜索,首先先从地图边缘开始进行广搜,将所有与地图边缘连接且字符为’O’的点用哈希表标注起来
- 之后遍历地图,对所有字符为‘O’,并且哈希表中不存在的点转化成‘X’。
3、克隆图
3.1 题目链接
点击跳转到题目位置
3.2 题目描述
给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆)。
图中的每个节点都包含它的值 val(int) 和其邻居的列表(list[Node])
测试用例格式:
简单起见,每个节点的值都和它的索引相同。例如,第一个节点值为 1(val = 1),第二个节点值为 2(val = 2),以此类推。该图在测试用例中使用邻接列表表示。
邻接列表 是用于表示有限图的无序列表的集合。每个列表都描述了图中节点的邻居集。
给定节点将始终是图中的第一个节点(值为 1)。你必须将 给定节点的拷贝 作为对克隆图的引用返回。
提示:
- 这张图中的节点数在 [0, 100] 之间。
- 1 <= Node.val <= 100
- 每个节点值 Node.val 都是唯一的,
- 图中没有重复的边,也没有自环。
- 图是连通图,你可以从给定节点访问到所有节点。
3.3 解题代码
/*
// Definition for a Node.
class Node {public int val;public List<Node> neighbors;public Node() {val = 0;neighbors = new ArrayList<Node>();}public Node(int _val) {val = _val;neighbors = new ArrayList<Node>();}public Node(int _val, ArrayList<Node> _neighbors) {val = _val;neighbors = _neighbors;}
}
*/class Solution {Map<Node, Node> hash = new HashMap<Node, Node>();public Node cloneGraph(Node node) {if(node == null){return null;}if(!hash.containsKey(node)){Node newNode = new Node(node.val);hash.put(node, newNode);for(int i = 0; i < node.neighbors.size(); ++i){newNode.neighbors.add(cloneGraph(node.neighbors.get(i)));}}return hash.get(node);}
}
3.4 解题思路
- 递归求解即可,题目与之前的138. 随机链表的复制一致。
4、除法求值
4.1 题目链接
点击跳转到题目位置
4.2 题目描述
给你一个变量对数组 equations 和一个实数值数组 values 作为已知条件,其中 equations[i] = [Ai, Bi] 和 values[i] 共同表示等式 Ai / Bi = values[i] 。每个 Ai 或 Bi 是一个表示单个变量的字符串。
另有一些以数组 queries 表示的问题,其中 queries[j] = [Cj, Dj] 表示第 j 个问题,请你根据已知条件找出 Cj / Dj = ? 的结果作为答案。
返回 所有问题的答案 。如果存在某个无法确定的答案,则用 -1.0 替代这个答案。如果问题中出现了给定的已知条件中没有出现的字符串,也需要用 -1.0 替代这个答案。
**注意:**输入总是有效的。你可以假设除法运算中不会出现除数为 0 的情况,且不存在任何矛盾的结果。
**注意:**未在等式列表中出现的变量是未定义的,因此无法确定它们的答案。
提示:
- 1 <= equations.length <= 20
- equations[i].length == 2
- 1 <= Ai.length, Bi.length <= 5
- values.length == equations.length
- 0.0 < values[i] <= 20.0
- 1 <= queries.length <= 20
- queries[i].length == 2
- 1 <= Cj.length, Dj.length <= 5
- Ai, Bi, Cj, Dj 由小写英文字母与数字组成
4.3 解题代码
class Solution {Map<String, Integer> hash = new HashMap<String, Integer>();int find(List<Integer> pre, List<Double> weight, int x){if(x != pre.get(x)){int origin = pre.get(x);pre.set(x, find(pre, weight, pre.get(x))); weight.set(x, weight.get(x) * weight.get(origin));}return pre.get(x);}void union(List<Integer> pre, List<Double> weight, double value, int x, int y){int index1 = find(pre, weight, x);int index2 = find(pre, weight, y);if(index1 != index2){pre.set(index1, index2);weight.set(index1, weight.get(y) * value / weight.get(x)); }}public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {int equationsSize = equations.size();int queriesSize = queries.size();double[] res = new double[queriesSize];int id = 0;List<Integer> pre = new ArrayList<>();List<Double> weight = new ArrayList<Double>();for(int i = 0; i < equationsSize; ++i){String str1 = equations.get(i).get(0);String str2 = equations.get(i).get(1);if(!hash.containsKey(str1)){hash.put(str1, id);pre.add(id);weight.add(1.0d);id++; }if(!hash.containsKey(str2)){hash.put(str2, id);pre.add(id);weight.add(1.0);id++;}union(pre, weight, values[i], hash.get(str1), hash.get(str2));}for(int i = 0; i < queriesSize; ++i){String str1 = queries.get(i).get(0);String str2 = queries.get(i).get(1);if(!hash.containsKey(str1) || !hash.containsKey(str2)){res[i] = -1.0;continue;}Integer id1 = hash.get(str1);Integer id2 = hash.get(str2);if(find(pre, weight, id1) != find(pre, weight, id2)){res[i] = -1.0d;continue;}double value1 = weight.get(id1);double value2 = weight.get(id2);res[i] = value1 / value2;}return res;}
}
4.4 解题思路
- 使用并查集解决问题。
5、课程表
5.1 题目链接
点击跳转到题目位置
5.2 题目描述
你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。
- 例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
提示:
- 1 <= numCourses <= 2000
- 0 <= prerequisites.length <= 5000
- prerequisites[i].length == 2
- 0 <= ai, bi < numCourses
- prerequisites[i] 中的所有课程对 互不相同
5.3 解题代码
class Solution {public boolean canFinish(int numCourses, int[][] prerequisites) {List<List<Integer>> edge = new ArrayList<>();for (int i = 0; i < numCourses; ++i) {edge.add(new ArrayList<>());}int[] deg = new int[numCourses];int n = prerequisites.length;for(int i = 0; i < n; ++i){int x = prerequisites[i][0];int y = prerequisites[i][1];deg[x]++;edge.get(y).add(x);}Queue<Integer> q = new LinkedList<Integer>();for(int i = 0; i < numCourses; ++i){if(deg[i] == 0){q.offer(i);}}while(!q.isEmpty()){int x = q.peek();q.poll();numCourses--;for(int i = 0; i < edge.get(x).size(); ++i){int num = edge.get(x).get(i);deg[num]--;if(deg[num] == 0){q.offer(num);}}}return numCourses == 0;}
}
5.4 解题思路
- 使用拓扑排序来解决问题
- 每次将度为0的结点放入队列中,每次从队首取点,并且numCourses–。如果最后图中存在环的话,则numCourses则不为0。
6、课程表 II
6.1 题目链接
点击跳转到题目位置
6.2 题目描述
现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。
- 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示:[0,1] 。
返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组 。
提示:
- 1 <= numCourses <= 2000
- 0 <= prerequisites.length <= numCourses * (numCourses - 1)
- prerequisites[i].length == 2
- 0 <= ai, bi < numCourses
- ai != bi
所有[ai, bi] 互不相同
6.3 解题代码
class Solution {public int[] findOrder(int numCourses, int[][] prerequisites) {int[] res = new int[numCourses];int k = 0;List<List<Integer>> edge = new ArrayList<>();for (int i = 0; i < numCourses; ++i) {edge.add(new ArrayList<>());}int[] deg = new int[numCourses];int n = prerequisites.length;for(int i = 0; i < n; ++i){int x = prerequisites[i][0];int y = prerequisites[i][1];deg[x]++;edge.get(y).add(x);}Queue<Integer> q = new LinkedList<Integer>();for(int i = 0; i < numCourses; ++i){if(deg[i] == 0){q.offer(i);}}while(!q.isEmpty()){int x = q.peek();res[k++] = x;q.poll();numCourses--;for(int i = 0; i < edge.get(x).size(); ++i){int num = edge.get(x).get(i);deg[num]--;if(deg[num] == 0){q.offer(num);}}}if(numCourses == 0){return res;}return new int[0];}
}
6.4 解题思路
- 使用拓扑排序解题
- 与上一题的区别就是需要把每次队首的元素放入结果数组中,最后符合条件的输出结果数组,否则输出空数组。
相关文章:

面试经典150题——图
文章目录 1、岛屿数量1.1 题目链接1.2 题目描述1.3 解题代码1.4 解题思路 2、被围绕的区域2.1 题目链接2.2 题目描述2.3 解题代码2.4 解题思路 3、克隆图3.1 题目链接3.2 题目描述3.3 解题代码3.4 解题思路 4、除法求值4.1 题目链接4.2 题目描述4.3 解题代码4.4 解题思路 5、课…...

学习数据结构(1)时间复杂度
1.数据结构和算法 (1)数据结构是计算机存储、组织数据的方式,指相互之间存在⼀种或多种特定关系的数据元素的集合 (2)算法就是定义良好的计算过程,取一个或一组的值为输入,并产生出一个或一组…...

项目集成GateWay
文章目录 1.环境搭建1.创建sunrays-common-cloud-gateway-starter模块2.目录结构3.自动配置1.GateWayAutoConfiguration.java2.spring.factories 3.pom.xml4.注意:GateWay不能跟Web一起引入! 1.环境搭建 1.创建sunrays-common-cloud-gateway-starter模块…...
【Ubuntu】使用远程桌面协议(RDP)在Windows上远程连接Ubuntu
使用远程桌面协议(RDP)在Windows上远程连接Ubuntu 远程桌面协议(RDP)是一种允许用户通过图形界面远程控制计算机的协议。本文将详细介绍如何在Ubuntu上安装和配置xrdp,并通过Windows的远程桌面连接工具访问Ubuntu。 …...
python3+TensorFlow 2.x 基础学习(一)
目录 TensorFlow 2.x基础 1、安装 TensorFlow 2.x 2、TensorFlow 2.x 基础概念 2、1 Eager Execution 2、2 TensorFlow 张量(Tensor) 3、使用Keras构建神经网络模型 3、1 构建 Sequential 模型 3、2 编译模型 1、Optimizer(优化器&a…...
《活出人生的厚度》
《活出人生的厚度》可以从不同角度来理解和实践,以下为你提供一些拓展内容: ### 不断学习与自我提升 - **持续知识更新**:保持对新知识的渴望,利用各种渠道学习,如在线课程、学术讲座、行业研讨会等。例如,…...

安装 docker 详解
在平常的开发工作中,我们经常需要部署项目。随着 Docker 容器的出现,大大提高了部署效率。Docker 容器包含了应用程序运行所需的所有依赖,避免了换环境运行问题。可以在短时间内创建、启动和停止容器,大大提高了应用的部署速度&am…...

【Rust自学】16.3. 共享状态的并发
喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 16.3.1. 使用共享来实现并发 还记得Go语言有一句名言是这么说的:Do not commun…...
开发者交流平台项目部署到阿里云服务器教程
本文使用PuTTY软件在本地Windows系统远程控制Linux服务器;其中,Windows系统为Windows 10专业版,Linux系统为CentOS 7.6 64位。 1.工具软件的准备 maven:https://archive.apache.org/dist/maven/maven-3/3.6.1/binaries/apache-m…...

【2024年华为OD机试】 (B卷,100分)- 乘坐保密电梯(JavaScriptJava PythonC/C++)
一、问题描述 问题描述 我们需要从0楼到达指定楼层m,乘坐电梯的规则如下: 给定一个数字序列,每次根据序列中的数字n,上升n层或下降n层。前后两次的方向必须相反,且首次方向向上。必须使用序列中的所有数字,不能只使用一部分。目标是到达指定楼层m,如果无法到达,则给出…...

maven的打包插件如何使用
默认的情况下,当直接执行maven项目的编译命令时,对于结果来说是不打第三方包的,只有一个单独的代码jar,想要打一个包含其他资源的完整包就需要用到maven编译插件,使用时分以下几种情况 第一种:当只是想单纯…...
solidity高阶 -- 线性继承
Solidity是一种面向合约的高级编程语言,用于编写智能合约。在Solidity中,多线继承是一个强大的特性,允许合约从多个父合约继承属性和方法。本文将详细介绍Solidity中的多线继承,并通过不同的实例展示其使用方法和注意事项。 在Sol…...
国内外大语言模型领域发展现状与预期
在数字化浪潮中,大语言模型已成为人工智能领域的关键力量,深刻影响着各个行业的发展轨迹。下面我们将深入探讨国内外大语言模型领域的发展现状以及未来预期。 一、发展现状 (一)国外进展 美国的引领地位:OpenAI 的 …...
【Leetcode 热题 100】416. 分割等和子集
问题背景 给你一个 只包含正整数 的 非空 数组 n u m s nums nums。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 数据约束 1 ≤ n u m s . l e n g t h ≤ 200 1 \le nums.length \le 200 1≤nums.length≤200 1 ≤ n u m s [ i ] ≤ …...

C语言------数组从入门到精通
1.一维数组 目标:通过思维导图了解学习一维数组的核心知识点: 1.1定义 使用 类型名 数组名[数组长度]; 定义数组。 // 示例: int arr[5]; 1.2一维数组初始化 数组的初始化可以分为静态初始化和动态初始化两种方式。 它们的主要区别在于初始化的时机和内存分配的方…...

物管系统赋能智慧物业管理提升服务质量与工作效率的新风潮
内容概要 在当今的物业管理领域,物管系统的崛起为智慧物业管理带来了新的机遇和挑战。这些先进的系统能够有效整合各类信息,促进数字化管理,从而提升服务质量和工作效率。通过物管系统,物业管理者可以实时查看和分析各种数据&…...

2024年记 | 凛冬将至
放弃幻想,准备斗争! 考研or就业? 上大学以来,考研上名校在我的心里一直是一颗种子,2024年初,当时的想法是考研和就业两手抓。买了张宇的高数现代,想要死磕! 也记了挺多笔记... 如果…...
MySQL数据导入与导出
在现代软件开发中,数据管理是一个重要的核心环节,而数据库则是进行数据管理的主要工具。MySQL 作为一款开源的关系型数据库管理系统,被广泛应用于企业和个人开发项目中。对于学习编程的初学者或是自学者来说,掌握 MySQL 的基本操作尤为重要,尤其是数据的导入与导出功能。这…...

NoSQL与SQL比较
1.认识NoSQL NoSql可以翻译做Not Only Sql(不仅仅是SQL),或者是No Sql(非Sql的)数据库。是相对于传统关系型数据库而言,有很大差异的一种特殊的数据库,因此也称之为非关系型数据库。 1.1.结构…...
Ceph:关于Ceph 中使用 RADOS 块设备提供块存储的一些笔记整理(12)
写在前面 准备考试,整理 ceph 相关笔记博文内容涉及使用 RADOS 块设备提供块存储理解不足小伙伴帮忙指正对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...