【算法与数据结构】417、LeetCode太平洋大西洋水流问题

文章目录

  • 一、题目
  • 二、解法
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、解法

  思路分析:题目要求雨水既能流向太平洋也能流向大西洋的网格。雨水流向取决于网格的高度。一个比较直接的方式是对每个网格做深度优先搜索,去判断该网格点是否连接太平洋和大西洋,连接的条件就是小于或者等于网格的高度。这样的方法对于当个网格点的复杂度是 O ( m × n ) O(m \times n) O(m×n),一共有 O ( m × n ) O(m \times n) O(m×n)个网格,总的复杂度是 O ( m 2 × n 2 ) O(m^2 \times n^2) O(m2×n2)。这种方法的缺点是没有利用点与点之间的关系,单个网格点的遍历不能再下一次遍历中利用。

  为了能充分利用点与点之间的关系,逆向思维一下,顺着雨水流向逆向遍历。从太平洋边上的节点出发,标记所有能流入太平洋的网格点;同样的方法,从大西洋边上的节点出发,标记所有能流入大西洋的的网格点。然后找到同时有太平洋和大西洋标记的节点输出。

  程序如下

// 417、太平洋大西洋水流问题
class Solution {
private:vector<vector<int>> result;vector<vector<int>> delta_x_y = { {0, -1}, {0, 1}, {-1, 0}, {1, 0} };	// 上下左右四个方向的偏移量void dfs(const vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y) {	// 1、递归输入参数visited[x][y] = true;// 3、单层递归逻辑for (int i = 0; i < 4; i++) {int nextx = x + delta_x_y[i][0];int nexty = y + delta_x_y[i][1];//  2、终止条件  逆流而上式的遍历 grid[nextx][nexty] < grid[x][y]if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size() || visited[nextx][nexty]  || grid[nextx][nexty] < grid[x][y]) continue;	dfs(grid, visited, nextx, nexty);}}
public:vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {vector<vector<bool>> pacific = vector<vector<bool>>(heights.size(), vector<bool>(heights[0].size(), false));	// 遍历过的坐标vector<vector<bool>> Atlanti = vector<vector<bool>>(heights.size(), vector<bool>(heights[0].size(), false));for (int i = 0; i < heights[0].size(); i++) {		// 遍历边界行dfs(heights, pacific, 0, i);				// 第一行dfs(heights, Atlanti, heights.size() - 1, i);	// 最后一行						}for (int j = 0; j < heights.size(); j++) {	// 遍历大西洋的网格点dfs(heights, pacific, j, 0);				// 第一列dfs(heights, Atlanti, j, heights[0].size() - 1);	// 最后一列			}for (int i = 0; i < heights.size(); i++) {	// 遍历行 for (int j = 0; j < heights[0].size(); j++) {	// 遍历列if (pacific[i][j] && Atlanti[i][j]) result.push_back({i, j});	// 深度优先搜索,将连接的陆地都标记上true}}return result;}
}; 

复杂度分析:

  • 时间复杂度: O ( m × n ) O(m \times n) O(m×n),其中 m m m n n n分别是网格数组的行数和列数。深度优先搜索的时间复杂度为 O ( m × n ) O(m \times n) O(m×n),主程序当中使用了四个for循环,前两个用来遍历边界,后两个用来遍历太平洋和大西洋的标记数组。前两个for循环的时间复杂度不是 O ( m × ( m × n ) + n × ( m × n ) ) = O ( ( m + n ) × ( m × n ) ) O(m \times (m \times n)+n \times (m \times n)) = O((m+n) \times (m \times n)) O(m×(m×n)+n×(m×n))=O((m+n)×(m×n))。因为我们引入了标记数组,标记过的网格不会多次遍历,实际上的复杂度是两个标记数组遍历的复杂度 O ( 2 × ( m × n ) ) O(2 \times (m \times n)) O(2×(m×n)),后两个循环的复杂度也是 O ( m × n ) O(m \times n) O(m×n)。因此总的时间复杂度为 O ( 3 × m × n ) = O ( m × n ) O(3 \times m \times n) = O(m \times n) O(3×m×n)=O(m×n)
  • 空间复杂度: O ( m × n ) O(m \times n) O(m×n)

三、完整代码

# include <iostream>
# include <vector>
# include <string>
using namespace std;// 417、太平洋大西洋水流问题
class Solution {
private:vector<vector<int>> result;vector<vector<int>> delta_x_y = { {0, -1}, {0, 1}, {-1, 0}, {1, 0} };	// 上下左右四个方向的偏移量void dfs(const vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y) {	// 1、递归输入参数visited[x][y] = true;// 3、单层递归逻辑for (int i = 0; i < 4; i++) {int nextx = x + delta_x_y[i][0];int nexty = y + delta_x_y[i][1];//  2、终止条件  逆流而上式的遍历 grid[nextx][nexty] < grid[x][y]if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size() || visited[nextx][nexty]  || grid[nextx][nexty] < grid[x][y]) continue;	dfs(grid, visited, nextx, nexty);}}
public:vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {vector<vector<bool>> pacific = vector<vector<bool>>(heights.size(), vector<bool>(heights[0].size(), false));	// 遍历过的坐标vector<vector<bool>> Atlanti = vector<vector<bool>>(heights.size(), vector<bool>(heights[0].size(), false));for (int i = 0; i < heights[0].size(); i++) {		// 遍历边界行dfs(heights, pacific, 0, i);				// 第一行dfs(heights, Atlanti, heights.size() - 1, i);	// 最后一行						}for (int j = 0; j < heights.size(); j++) {	// 遍历大西洋的网格点dfs(heights, pacific, j, 0);				// 第一列dfs(heights, Atlanti, j, heights[0].size() - 1);	// 最后一列			}for (int i = 0; i < heights.size(); i++) {	// 遍历行 for (int j = 0; j < heights[0].size(); j++) {	// 遍历列if (pacific[i][j] && Atlanti[i][j]) result.push_back({i, j});	// 深度优先搜索,将连接的陆地都标记上true}}return result;}
}; void my_print(vector<vector<int>> result, string message) {cout << message << endl;for (vector<vector<int>>::iterator it = result.begin(); it != result.end(); it++) {for (vector<int>::iterator jt = (*it).begin(); jt != (*it).end(); jt++) {cout << *jt << " ";}cout << endl;}
}int main() {//vector<vector<int>> 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} };//vector<vector<int>> heights = { {1} };vector<vector<int>> heights = { {3,3,3,3,3,3}, {3,0,3,3,0,3 }, {3,3,3,3,3,3} };Solution s1;vector<vector<int>> result = s1.pacificAtlantic(heights);my_print(result, "结果:");system("pause");return 0;
}

end

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

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

相关文章

《TCP/IP详解 卷一》第4章 地址解析协议ARP

目录 4.1 引言 4.2 一个例子 4.3 ARP缓存 4.4 ARP帧格式 4.5 ARP例子 4.6 ARP缓存超时 4.7 代理ARP 4.8 免费ARP和地址冲突检测 4.9 ARP命令 4.10 使用ARP设置嵌入式设备IPv4地址 4.11 与ARP相关攻击 4.12 总结 4.1 引言 地址解析&#xff1a; IPv4&#xff1a;AR…

社交媒体变革者:剖析Facebook对在线互动的贡献

随着数字化时代的蓬勃发展&#xff0c;社交媒体已经成为人们日常生活中不可或缺的一部分。在这个领域的发展中&#xff0c;Facebook作为先行者和领导者&#xff0c;对在线互动的演变和发展产生了深远的影响。本文将深入剖析Facebook在社交媒体领域的贡献&#xff0c;以及它对在…

MySql-DQL-条件查询

目录 条件查询修改数据 查询 姓名 为 Name10 的员工查询 id小于等于5 的员工信息查询 没有分配职位 的员工信息查询 有职位 的员工信息查询 密码不等于 password1 的员工信息查询 入职日期 在 2000-01-01 (包含) 到 2010-01-01(包含) 之间的员工信息查询 入职时间 在 2000-01-0…

跨区互联组网怎么做?SD-WAN专线可以实现吗?

在当今数字化时代&#xff0c;企业不断扩张&#xff0c;跨区域互联成为业务发展的必然需求。然而&#xff0c;跨区互联组网涉及到复杂的网络架构和连接&#xff0c;传统的网络方案往往难以满足高性能、高可靠性和低成本的要求。SD-WAN专线技术的出现&#xff0c;为跨区互联组网…

C++:Level2阶段测试

总结。 只要你看过我的文章&#xff0c;哪怕只是一半&#xff0c;一定能够过关&#xff01; 准备好开始测试氻吗&#xff1f; 判断题&#xff0c;每题4分&#xff0c;共100分 1、Red Panda Dev C Maker【3.0自创黑客版】添加的头文件有Heike.h&#xff08;&#xff09; 2、在…

Java 学习和实践笔记(19):this的使用方法

this用来指向当前对象的地址。 this的用法&#xff1a; 1&#xff09;在普通方法中&#xff0c;this总是指向调用该方法的对象。在普通方法中&#xff0c;它是作为一种隐式参数一直就存在着&#xff08;这句话的意思&#xff0c;就是其实在普通方法中&#xff0c;编译器一直就…

go使用trpc案例

1.go下载trpc go install trpc.group/trpc-go/trpc-cmdline/trpclatest 有报错的话尝试配置一些代理&#xff08;选一个&#xff09; go env -w GOPROXYhttps://goproxy.cn,direct go env -w GOPROXYhttps://goproxy.io,direct go env -w GOPROXYhttps://goproxy.baidu.com/…

Django学习笔记-forms使用

1.创建forms.py文件,导入包 from django import forms from django.forms import fields from django.forms import widgets2. 创建EmployeeForm,继承forms.Form 3.创建testform.html文件 4.urls.py添加路由 5.views中导入forms 创建testform,编写代码 1).如果请求方式为GET,…

go 1.18 不同目录package引用问题

go 1.18开始使用module了 不同的package在vs code中引用的话 需要先开启 是Go1.11版本之后 推出的版本管理工具 有点类似java的 maven工具 可以引入依赖使用 go env -w GO111MODULEon 先把这个打开 然后在创建的vs code工作目录下 执行 module gomdoule module 模块名 会生…

如何将新标注的三元组数据转换成unicoqe可以处理的格式

目录 问题描述&#xff1a; 问题解决&#xff1a; 问题描述&#xff1a; 原始的标注的三元组格式如下&#xff1a; 需要转换的格式如下&#xff1a; tips:有一个小的难点&#xff1a; 1. 针对多三元组的情况&#xff0c;需要额外考虑 2. 最后一个样本&#xff0c;也记得需要…

CentOS7 安装SSH

说实话&#xff0c;感觉CentOS有点难用。初始配置不是很友好&#xff0c;连自动获取IP地址都是关着的。当然&#xff0c;我这里本地用的是虚拟机。 开启获取IP 首先是获取IP地址&#xff0c;这是一些的起点。 首先使用ip addr 看看网卡地址和名称。我这边是ens33。然后打开自…

【踩坑专栏】主机ping虚拟机失败

我出现的问题finalshell连接超时&#xff0c;ping了一下发现ping都ping不通&#xff0c;于是发现问题所在。 最开始我是把虚拟机的网络设置改为桥接模式&#xff0c;问题解决了&#xff0c;但是这种模式的问题就是每次开机&#xff0c;ip都会改变&#xff0c;因此非常麻烦&…

C++从入门到精通 第七章(结构体)

写在前面&#xff1a; 本系列专栏主要介绍C的相关知识&#xff0c;思路以下面的参考链接教程为主&#xff0c;大部分笔记也出自该教程&#xff0c;笔者的原创部分主要在示例代码的注释部分。除了参考下面的链接教程以外&#xff0c;笔者还参考了其它的一些C教材&#xff08;比…

SQLMap详解

SQLMap是一个自动化的SQL注入工具&#xff0c;其主要功能是扫描、发现并利用给定 URL的 SQL注入漏洞&#xff0c;内置了很多绕过插件&#xff0c;支持的数据库是MySQL、Oracle、 PostgreSQL、Microsoft SQL Server、Microsoft Access、IBM DB2、SQLite、 Firebird、Sybase和SAP…

【初中生讲机器学习】11. 回归算法中常用的模型评价指标有哪些?here!

创建时间&#xff1a;2024-02-19 最后编辑时间&#xff1a;2024-02-23 作者&#xff1a;Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏&#xff0c;很高兴遇见你~ 我是 Geeker_LStar&#xff0c;一名初三学生&#xff0c;热爱计算机和数学&#xff0c;我们一起加…

数据库管理-第154期 Oracle Vector DB AI-06(20240223)

数据库管理154期 2024-02-23 数据库管理-第154期 Oracle Vector DB & AI-06&#xff08;20240223&#xff09;1 环境准备创建表空间及用户TNSNAME配置 2 Oracle Vector的DML操作创建示例表插入基础数据DML操作UPDATE操作DELETE操作 3 多Vector列表4 固定维度的向量操作5 不…

二手货wordpress企业网站主题模板

二手车wordpress主题模板 简洁的二手车wordpress主题模板&#xff0c;适合做二手车业务的公司官方网站使用。 https://www.jianzhanpress.com/?p3473 wordpress二手物资回收主题 绿色wordpress二手物资回收主题&#xff0c;用于二手物资回收公司WP建站使用。 https://www.…

关于Kinect 互动沙盘 深度图 Shader Graph 分层

把Kinect的深度图穿给Shader Graph using com.rfilkov.kinect; using UnityEngine; using UnityEngine.UI; public class GetDepthTex : MonoBehaviour { public Material Mat_SandTable; void Update() { Mat_SandTable.SetTexture("_MainTex"…

第十二天-ppt的操作

目录 创建ppt文档 安装 使用 段落的使用 段落添加数据 段落中定义多个段落 自定义段落 ppt插入表表格 PPT插入图片 读取ppt 读取ppt整体对象 ​编辑 获取ppt文本 获取表格内容 创建ppt文档 安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple python…

ES通用查询页面使用说明

前言:ES语法比较复杂,需要专门的学习,而且查询工具不太友好, 对公司运维人员使用有点困难,所以花了个时间做了一个页面,方便运维人员使用,如下。 也不难,有兴趣的朋友可以私聊发源码。 开发帮助-ES数据查询 搜索 输入要查看的文档索引,文档类型后点【查询】即可 搜…