图论基础|417. 太平洋大西洋水流问题、827.最大人工岛、127. 单词接龙

目录

417. 太平洋大西洋水流问题

827.最大人工岛

127. 单词接龙


417. 太平洋大西洋水流问题

题目链接(opens new window)

有一个 m × n 的矩形岛屿,与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界,而 “大西洋” 处于大陆的右边界和下边界。

这个岛被分割成一个由若干方形单元格组成的网格。给定一个 m x n 的整数矩阵 heights , heights[r][c] 表示坐标 (r, c) 上单元格 高于海平面的高度 。

岛上雨水较多,如果相邻单元格的高度 小于或等于 当前单元格的高度,雨水可以直接向北、南、东、西流向相邻单元格。水可以从海洋附近的任何单元格流入海洋。

返回网格坐标 result 的 2D 列表 ,其中 result[i] = [ri, ci] 表示雨水从单元格 (ri, ci) 流动 既可流向太平洋也可流向大西洋 。

示例 1:

  • 输入: heights = [[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]
  • 输出: [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]

示例 2:

  • 输入: heights = [[2,1],[1,2]]
  • 输出: [[0,0],[0,1],[1,0],[1,1]]

提示:

  • m == heights.length
  • n == heights[r].length
  • 1 <= m, n <= 200
  • 0 <= heights[r][c] <= 10^5

思路:

那么我们可以 反过来想,从太平洋边上的节点 逆流而上,将遍历过的节点都标记上。 从大西洋的边上节点 逆流而长,将遍历过的节点也标记上。 然后两方都标记过的节点就是既可以流太平洋也可以流大西洋的节点。

从太平洋边上节点出发,如图:

图一

从大西洋边上节点出发,如图:

图二

class Solution {
public://dfs版int dir[4][2]={1,0,0,1,-1,0,0,-1};//方向void dfs(vector<vector<int>>& heights, vector<vector<bool>>& visited, int x, int y){if(visited[x][y])return;visited[x][y]=true;for(int i=0;i<4;i++){int nextx = x+dir[i][0];int nexty = y+dir[i][1];if(nextx<0||nextx>=heights.size()||nexty<0||nexty>=heights[0].size())continue;if(heights[x][y]>heights[nextx][nexty])continue;  //大于或等于当前才能流通,否则跳过dfs(heights, visited, nextx, nexty);// visited[nextx][nexty]=true;}return;}vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {int n=heights.size();//列数int m=heights[0].size();//行数vector<vector<bool>>pacificVisited(n,vector<bool>(m,false));vector<vector<bool>>atlanticVisited(n,vector<bool>(m,false));//从边上分别遍历for(int i=0;i<n;i++){dfs(heights, pacificVisited, i,0);//遍历最顶上dfs(heights,atlanticVisited,i,m-1);//遍历最底下}for(int j=0;j<m;j++){dfs(heights, pacificVisited, 0, j);//遍历最左边dfs(heights, atlanticVisited, n-1,j); //遍历最右边}vector<vector<int>>result;//遍历整个地图for(int i=0;i<n;i++){for(int j=0; j<m;j++){if(pacificVisited[i][j]&&atlanticVisited[i][j]){result.push_back({i,j});}}}return result;}
};

827.最大人工岛

力扣链接(opens new window)

给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。

返回执行此操作后,grid 中最大的岛屿面积是多少?

岛屿 由一组上、下、左、右四个方向相连的 1 形成。

示例 1:

  • 输入: grid = [[1, 0], [0, 1]]
  • 输出: 3
  • 解释: 将一格0变成1,最终连通两个小岛得到面积为 3 的岛屿。

示例 2:

  • 输入: grid = [[1, 1], [1, 0]]
  • 输出: 4
  • 解释: 将一格0变成1,岛屿的面积扩大为 4。

示例 3:

  • 输入: grid = [[1, 1], [1, 1]]
  • 输出: 4
  • 解释: 没有0可以让我们变成1,面积依然为 4。

思路:

只要用一次深搜把每个岛屿的面积记录下来就好。

第一步:一次遍历地图,得出各个岛屿的面积,并做编号记录。可以使用map记录,key为岛屿编号,value为岛屿面积 第二步:在遍历地图,遍历0的方格(因为要将0变成1),并统计该1(由0变成的1)周边岛屿面积,将其相邻面积相加在一起,遍历所有 0 之后,就可以得出 选一个0变成1 之后的最大面积。

class Solution {
private:int count;int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向void dfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y, int mark) {if (visited[x][y] || grid[x][y] == 0) return; // 终止条件:访问过的节点 或者 遇到海水visited[x][y] = true; // 标记访问过grid[x][y] = mark; // 给陆地标记新标签count++;for (int i = 0; i < 4; i++) {int nextx = x + dir[i][0];int nexty = y + dir[i][1];if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue;  // 越界了,直接跳过dfs(grid, visited, nextx, nexty, mark);}}public:int largestIsland(vector<vector<int>>& grid) {int n = grid.size(), m = grid[0].size();vector<vector<bool>> visited = vector<vector<bool>>(n, vector<bool>(m, false)); // 标记访问过的点unordered_map<int ,int> gridNum;int mark = 2; // 记录每个岛屿的编号bool isAllGrid = true; // 标记是否整个地图都是陆地for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (grid[i][j] == 0) isAllGrid = false;if (!visited[i][j] && grid[i][j] == 1) {count = 0;dfs(grid, visited, i, j, mark); // 将与其链接的陆地都标记上 truegridNum[mark] = count; // 记录每一个岛屿的面积mark++; // 记录下一个岛屿编号}}}if (isAllGrid) return n * m; // 如果都是陆地,返回全面积// 以下逻辑是根据添加陆地的位置,计算周边岛屿面积之和int result = 0; // 记录最后结果unordered_set<int> visitedGrid; // 标记访问过的岛屿for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {int count = 1; // 记录连接之后的岛屿数量visitedGrid.clear(); // 每次使用时,清空if (grid[i][j] == 0) {for (int k = 0; k < 4; k++) {int neari = i + dir[k][1]; // 计算相邻坐标int nearj = j + dir[k][0];if (neari < 0 || neari >= grid.size() || nearj < 0 || nearj >= grid[0].size()) continue;if (visitedGrid.count(grid[neari][nearj])) continue; // 添加过的岛屿不要重复添加// 把相邻四面的岛屿数量加起来count += gridNum[grid[neari][nearj]];visitedGrid.insert(grid[neari][nearj]); // 标记该岛屿已经添加过}}result = max(result, count);}}return result;}
};

127. 单词接龙

力扣题目链接(opens new window)

字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列:

  • 序列中第一个单词是 beginWord 。
  • 序列中最后一个单词是 endWord 。
  • 每次转换只能改变一个字母。
  • 转换过程中的中间单词必须是字典 wordList 中的单词。
  • 给你两个单词 beginWord 和 endWord 和一个字典 wordList ,找到从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0。

示例 1:

  • 输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
  • 输出:5
  • 解释:一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。

示例 2:

  • 输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
  • 输出:0
  • 解释:endWord "cog" 不在字典中,所以无法进行转换

思路:最短路径,考虑广度优先搜索;为了提升查找效率,可以采用哈希结构,将单词列表转换到unodered_set,将路径与长度放到unodered_map<string, int>里;每次查找时,用两个for循环,一个for循环遍历beginword进行字母替换,另一个循环遍历26个字母,依次进行替换,再看看替换后字母有没有出现在单词集合unodered_set里,如果出现了:假如正好==endword,路径长度+1,返回结果;否则路径长度+1,继续进行搜索

class Solution {
public:int ladderLength(string beginWord, string endWord, vector<string>& wordList) {unordered_set<string>wordset(wordList.begin(), wordList.end());if(wordset.find(endWord)==wordset.end())return 0;unordered_map<string,int> visitedmap;//记录单词及对应路径长度queue<string>que;que.push(beginWord);visitedmap.insert(pair<string,int>(beginWord,1));//第一个单词,路径1while(!que.empty()){string word=que.front(); que.pop();int pathlen=visitedmap[word];for(int i=0;i<word.size();i++){string newword=word;for(int j=0;j<26;j++){newword[i]=j+'a';if(newword==endWord)return pathlen+1;//判断新字符串是否在单词集合里面,如果在,说明有效;//再看新单词是否在路径集合里出现过,如果有效且未出现在路径里,那么加入路径,路径长度+1,继续2迭代if(wordset.find(newword)!=wordset.end()&&visitedmap.find(newword)==visitedmap.end()){visitedmap.insert(pair<string,int>(newword,pathlen+1));que.push(newword);}}}}return 0;}
};

 参考:代码随想录

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

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

相关文章

数据分析POWER BI之power query

1.导入数据 ctrla全选--数据--获取数据--其他来源--来自表格/区域 导入数据&#xff0c;进入编辑模式 2.整理与清除 清除&#xff1a;删除所选列的非打印字符 转换--格式--清除 修整&#xff1a;删除前面和后面的空格 转换---格式---修整&#xff08;修整后前面后面的空格没有了…

程序汪若依微服务华为云Linux部署保姆教程

若依官方有3个版本&#xff0c;程序汪以前已经出了对应的安装部署视频教程 单应用版本 前后分离版本 微服务版本 本视频是若依微服务版本&#xff0c;如果基础的环境软件都不会安装建议看下程序汪的单应用和前后端分离版本教程&#xff0c; 欢迎点击进入 &#xff08;单应…

【VALL-E-02】核心原理

本文系个人知乎专栏文章迁移 VALL-E 网络是GPT-SOVITS很重要的参考 知乎专栏地址&#xff1a; 语音生成专栏 相关文章链接&#xff1a; 【VALL-E-01】环境搭建 【VALL-E-02】核心原理 【参考】 【1】Neural Codec Language Models are Zero-Shot Text to Speech Synthesiz…

部署单节点k8s并允许master节点调度pod

安装k8s 需要注意的是k8s1.24 已经弃用dockershim&#xff0c;现在使用docker需要cri-docker插件作为垫片&#xff0c;对接k8s的CRI。 硬件环境&#xff1a; 2c2g 主机环境&#xff1a; CentOS Linux release 7.9.2009 (Core) IP地址&#xff1a; 192.168.44.161 一、 主机配…

C++ 子序列

目录 最长递增子序列 摆动序列 最长递增子序列的个数 最长数对链 最长定差子序列 最长的斐波那契子序列的长度 最长等差数列 等差数列划分 II - 子序列 最长递增子序列 300. 最长递增子序列 子数组是连续的&#xff0c;子序列可以不连续&#xff0c;那么就要去[0, i - 1]…

GuLi商城-商品服务-API-三级分类-查询-树形展示三级分类数据

1、网关服务配置路由 2、商品服务 3、启动本地nacos&#xff0c;打开nacos地址看nacos服务列表 4、编写VUE <template> <el-tree :data"menus" :props"defaultProps" node-click"handleNodeClick"></el-tree> </template…

下载网页上的在线视频 网络视频 视频插件下载

只需要在浏览器上安装一个插件&#xff0c;就可以下载大部分的视频文件&#xff0c;几秒到一两个小时的视频&#xff0c;基本都不是问题。详细解决如下&#xff1a; 0、因为工作需要&#xff0c;需要获取某网站上的宣传视频&#xff0c;我像往常一样&#xff0c;查看视频的url…

802.1X网络访问控制协议

802.1X是一种由IEEE&#xff08;电气和电子工程师协会&#xff09;制定的网络访问控制协议&#xff0c;主要用于以太网和无线局域网&#xff08;WLAN&#xff09;中基于端口的网络接入控制。802.1X协议通过认证和授权机制&#xff0c;确保只有合法的用户和设备才能够接入网络&a…

VPCFormer:一个基于transformer的多视角指静脉识别模型和一个新基准

文章目录 VPCFormer:一个基于transformer的多视角指静脉识别模型和一个新基准总结摘要介绍相关工作单视角指静脉识别多视角指静脉识别Transformer 数据库基本信息 方法总体结构静脉掩膜生成VPC编码器视角内相关性的提取视角间相关关系提取输出融合IFFN近邻感知模块(NPM) patch嵌…

程序员实用学习平台,必看榜!

只要卷不死&#xff0c;就往死里卷&#xff01; 高中老师宣扬的励志鸡汤&#xff0c;仿佛走出了校园踏入社会仍然适用。 “出走半生&#xff0c;归来仍是少年。”emm....... 如今比麻花还卷的社会&#xff0c;学到老才能活到老啊~尤其咱们IT这么优胜劣汰的行业&#xff0c;自是…

性能测试百分百会问到且难度极高的面试题分享给大家,面试了16家公司,都有被问到!

今天给大家分享一波面试中经常被问到性能指标&#xff0c;希望能帮助大家&#xff0c;建议收藏&#xff5e; 1、吞吐量 单位时间内&#xff0c;系统能够处理多少请求&#xff0c;吞吐量代表网络的流量&#xff0c;TPS越高&#xff0c;吞吐量越大&#xff0c;还包含了数据的吞…

Web常见标签属性

应用软件&#xff1a;c/s&#xff08;客户端与服务端&#xff09; b/s&#xff08;服务器与浏览器架构&#xff09;web前端&#xff1a;html5、css3、JavaScriptHtml5&#xff1a;超文本标记语言 超链接标签 语法规范<标签名> marquee 标签之间可以嵌套属性&#xff1a;…

第九届蓝桥杯大赛个人赛省赛(软件类)真题C 语言 A 组-乘积尾零

solution 找末尾0的个数&#xff0c;即找有多少对2和5 >问题等价于寻找所给数据中&#xff0c;有多少个2和5的因子&#xff0c;较少出现的因子次数即为0的个数 #include <iostream> using namespace std; int main() {// 请在此输入您的代码printf("31");…

【机器学习300问】44、P-R曲线是如何权衡精确率和召回率的?

关于精确率和召回率的基础概念我已经写了两篇文章&#xff0c;如果友友还不知道这两个评估指标是什么&#xff0c;可以先移步去看看这两篇文章&#xff1a; 【机器学习300问】25、常见的模型评估指标有哪些&#xff1f;http://t.csdnimg.cn/JtuUO 总结一下这两个概念&a…

C语言动态内存管理

CSDN成就一亿技术人 目录 一.为什么要存在动态内存分配 二.动态内存函数 1.malloc和free 2.calloc 3.realloc 三.常见的动态内存错误 1.对NULL指针的解引用操作 2.对动态开辟空间的越界访问 3.对非动态开辟内存使用free释放 4.使用free释放一块动态开辟内存的一…

总结虚函数表机制——c++多态底层原理

前言&#xff1a; 前几天学了多态。 然后过去几天一直在测试多态的底层与机制。今天将多态的机制以及它的本质分享给受多态性质困扰的友友们。 本节内容只涉及多态的原理&#xff0c; 也就是那张虚表的规则&#xff0c;有点偏向底层。 本节不谈语法&#xff01;不谈语法&#x…

【MySQL】InnoDB引擎

逻辑结构 InnoDB存储引擎逻辑结构如图所示&#xff1a; Tablespace&#xff1a;表空间&#xff0c;一个数据库可以对应多个表空间。数据库中的每张表都有一个表空间&#xff0c;用来存放表记录、索引等数据。 Segment&#xff1a;段&#xff0c;表空间中有多个段&#xff0c…

R语言迅速计算多基因评分(PRS)

Polygenic Risk Scores in R 最朴素的理解PRS&#xff1a; GWAS分析结果中&#xff0c;有每个SNP的beta值、se值、P值&#xff0c;因为GWAS分析中将SNP变为0-1-2编码&#xff0c;所以这些显著的SNP的beta值&#xff0c;就可以用于预测。 比如&#xff1a;GWAS分析中&#xf…

iOS开发之SwiftUI

iOS开发之SwiftUI 在iOS开发中SwiftUI与Objective-C和Swift不同&#xff0c;它采用了声明式语法&#xff0c;相对而言SwiftUI声明式语法简化了界面开发过程&#xff0c;减少了代码量。 由于SwiftUI是Apple推出的界面开发框架&#xff0c;从iOS13开始引入&#xff0c;Apple使用…

成为创作者的第 730 天——创作纪念日

​​ 文章目录 &#x1f4e8; 官方致信&#x1f3af;我的第一篇文章&#x1f9e9; 机缘与成长 &#x1f3af; 成就&#x1f3af; 目标 &#x1f4e8; 官方致信 今天早上打开 CSDN 私信一看&#xff0c;看到了这一条消息&#xff0c;然后看了下日期。突然感慨到&#xff0c;是…