当前位置: 首页 > news >正文

LeetCode 417 - 太平洋大西洋水流问题

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

文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

这道题看起来像地理模拟,但其实是个非常典型的「图搜索 + 反向思考」问题。
我们要找出能同时流向太平洋(左上边界)和大西洋(右下边界)的所有坐标点。
题目乍看复杂,其实核心思路只有一句话:从海洋反向出发,找出能到达的点。

描述

我们有一个 m x n 的矩阵,heights[r][c] 表示高度。
水只能往高度不高于当前点的方向流动(即水往低处流),并且如果从某个点出发能顺流流到边界,那么这个点就能流向对应的海洋。

任务:
返回所有“既能流向太平洋,又能流向大西洋”的点的坐标。

示例:

输入:
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]]

题解答案

如果我们从每个格子出发去判断“能否到达太平洋和大西洋”,复杂度会很高,因为每个点都要 DFS 一次。
但我们可以换个思路:

与其让水往下流,不如让海洋往上“反爬”。

也就是说,从太平洋边界开始,找到所有能“逆流而上”的格子(即可以从这个格子流到太平洋的格子);
同理,从大西洋边界也做一次相同的搜索;
最后取两个结果的交集,就是答案。

题解代码分析

我们用 DFS(或 BFS)搜索所有能从海洋“逆流”到的点。
这段 Swift 代码使用 DFS 实现,逻辑简洁且易读。

import Foundationclass Solution {func pacificAtlantic(_ heights: [[Int]]) -> [[Int]] {guard !heights.isEmpty else { return [] }let rows = heights.countlet cols = heights[0].countvar pacific = Array(repeating: Array(repeating: false, count: cols), count: rows)var atlantic = Array(repeating: Array(repeating: false, count: cols), count: rows)let directions = [(1,0),(-1,0),(0,1),(0,-1)]func dfs(_ r: Int, _ c: Int, _ visited: inout [[Bool]], _ prevHeight: Int) {// 越界或高度不满足条件直接返回guard r >= 0, c >= 0, r < rows, c < cols else { return }if visited[r][c] || heights[r][c] < prevHeight { return }visited[r][c] = truefor (dr, dc) in directions {dfs(r + dr, c + dc, &visited, heights[r][c])}}// 从太平洋边界出发for c in 0..<cols {dfs(0, c, &pacific, heights[0][c])dfs(rows - 1, c, &atlantic, heights[rows - 1][c])}// 从大西洋边界出发for r in 0..<rows {dfs(r, 0, &pacific, heights[r][0])dfs(r, cols - 1, &atlantic, heights[r][cols - 1])}var result = [[Int]]()for r in 0..<rows {for c in 0..<cols {if pacific[r][c] && atlantic[r][c] {result.append([r, c])}}}return result}
}

代码解析:

  1. pacificatlantic 两个二维布尔矩阵用于标记哪些点能被对应的海洋“触及”;
  2. dfs 函数执行深度优先遍历,沿着比当前高度更高或相等的路径前进;
  3. 从太平洋边界(上边和左边)开始 DFS;
  4. 从大西洋边界(下边和右边)开始 DFS;
  5. 最后遍历整个矩阵,找到同时被两者访问过的点,即为答案。

换句话说:我们不让水流动,而是让海水“倒灌”上山。

示例测试及结果

我们可以通过下面的示例来验证:

let solution = Solution()
let 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]
]
print(solution.pacificAtlantic(heights))

输出结果:

[[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]

如果我们画出来,大概可以理解为:

  • 从左上边(太平洋)能“逆流而上”的点;
  • 从右下边(大西洋)也能“逆流而上”的点;
  • 两者重叠区域就是水能两边都流到的地方。

这个方法直观又高效。

时间复杂度

每个格子只会在 DFS 中被访问一次,因此:

时间复杂度为 O(M × N)
其中 M 和 N 分别是矩阵的行数和列数。

空间复杂度

我们用了两个 M × N 的布尔矩阵以及 DFS 栈空间,

所以空间复杂度为 O(M × N)

总结

这道题的关键不在于“水怎么流”,而在于从哪里出发思考
一旦你反过来想,就会发现问题瞬间清晰。

这类题的思维模式可以推广到很多实际开发场景,比如:

  • 地图路径可达性计算(例如在导航系统中判断哪些区域可达)
  • 洪水或扩散模拟(例如地形渲染、游戏地图)
  • 双源搜索问题(例如同时满足两个条件的节点查找)
http://www.dtcms.com/a/578255.html

相关文章:

  • kamailio+rtpengine对sdp的处理
  • 深圳市制作网站上海跨境电商网站制作
  • 今日行情明日机会——20251106
  • 短视频制作app网站内部优化怎么做
  • qq钓鱼网站制作建设展示类网站的意义
  • Windows通过WSL2安装Docker
  • ART虚拟机 | 类加载详解
  • 做面包网站wordpress外贸发布接口
  • 【AI应用探索】-7- LLaMA-Factory微调模型
  • AWS Elastic Beanstalk 实现 Java 应用高可用部署指南
  • 监理网站河南网站seo营销多少费用
  • 网站的注册做网站需要提供什么条件
  • 密码学系统的核心防护:FUZZ测试(模糊测试)技术原理与行业实践
  • ubuntu20.0.4源码安装Colmap流程
  • 做网站卖东西送上门网站title的写法
  • Windows 系统安装 Composer 详细教程
  • wordpress 切换域名网站代码优化有哪些
  • 中小工厂erp管理系统济南网站建设seo优化
  • 国产ASP4644I6B降压稳压器在工业仪表中的应用实践与分析
  • TRO侵权预警|Theodoros爆款食物插画发起版权维权
  • 4.1 Boost库工具类noncopyable的使用
  • ubuntu连接airpods
  • wordpress评分点评成都网站搭建优化推广
  • 保山手机网站建设影视公司网站建设
  • Poll 服务器实战教学:从 Select 迁移到更高效的多路复用
  • 代码管理——VS Code|Git
  • SkyWalking运维之路(Java探针接入)
  • 四川省建设厅注册中心网站wordpress主页加音乐
  • 广州企业网站模板建站专业做阿里巴巴网站的公司
  • 网站的ftp账号和密码谷歌外贸建站