Leetcode0417. 太平洋大西洋水流问题(medium)

目录

1. 题目描述 

2. 解题分析

3. 代码实现


1. 题目描述 

有一个 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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/pacific-atlantic-water-flow
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题分析

        这道题目的描述有一点点含糊的地方。应该是要找岛上的水既能流向太平洋又能流向大西洋的岛屿。

        左下和右上两个岛显然都满足条件。

        上边和左边两条边上的岛显然可以到达太平洋,而右边和下边两条边上的岛显然可以到达大西洋。但是各自能否到达另一个大洋需要查询。

        显然这是一个可到达性的问题(reachability),但是也不是一个单纯的单源可到达性问题,而是像leetcode1162一样属于多源问题。

        考虑从上、左两条边上的岛出发搜索能到达太平洋的岛屿连通区域,其中邻接岛屿定义为能够按照题设规则到达本岛的上下左右的岛,记所得的联通集合为islandSet1。

        考虑从下、右两条边上的岛出发搜索能到达太平洋的岛屿连通区域,记所得的联通集合为islandSet2。

        islandSet1和islandSet2的交集即为所求集合。

        需要是需要遍历所有格点,所有广度优先搜索和深度优先搜索都可以。

        需要注意的是,每个格点可能需要经过多次判断才能被判断能够加入connected,因为,一个格点有可能通过四个方向的任何一个方向与当前连通区域连通。所以,这里不需要或者不能用常规的访问过依次就加入其中的visited。connected1(2)就起到visited管理的作用。

3. 代码实现

from typing import List
from collections import deque

class Solution:
    def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
        
        R,C        = len(heights),len(heights[0])

        q          = deque([(0,k) for k in range(C)] + [(k,0) for k in range(1,R)])
        connected1 = set([(0,k) for k in range(C)] + [(k,0) for k in range(1,R)])
        
        while len(q) > 0:
            r,c = q.popleft()
            for x,y in [(r-1,c),(r+1,c),(r,c-1),(r,c+1)]:
                if 0<=x<R and 0<=y<C and (x,y) not in connected1:
                    if heights[x][y] >= heights[r][c]:
                        connected1.add((x,y))
                        q.append((x,y))
        print(connected1)

        q          = deque([(R-1,k) for k in range(C)] + [(k,C-1) for k in range(R-1)])
        connected2 = set([(R-1,k) for k in range(C)] + [(k,C-1) for k in range(R-1)])
        
        while len(q) > 0:
            r,c = q.popleft()
            for x,y in [(r-1,c),(r+1,c),(r,c-1),(r,c+1)]:
                if 0<=x<R and 0<=y<C and (x,y) not in connected2:
                    if heights[x][y] >= heights[r][c]:
                        connected2.add((x,y))
                        q.append((x,y))
        print(connected2)
            
        return list(connected2.intersection(connected1))
                        
if __name__ == '__main__':
    sln = Solution()

    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(sln.pacificAtlantic(heights))  

    heights = [[2,1],[1,2]]
    print(sln.pacificAtlantic(heights))  

        执行用时:72 ms, 在所有 Python3 提交中击败了94.03%的用户

        内存消耗:16.3 MB, 在所有 Python3 提交中击败了71.30%的用户

        比较自豪的一个结果。

        补充@2022-04-27

        本题在之前图论基础学习计划中做过,但是每日一题要求也必须重新提交了一下。于是没有做任何代码重新提交了一下,结果如下:

        执行用时:84 ms, 在所有 Python3 提交中击败了81.17%的用户

        内存消耗:16.1 MB, 在所有 Python3 提交中击败了93.83%的用户

        这个排名数据的变化情况令我很惊讶。两项相对数据发生变化可以理解,执行用时嘛,跟服务器的当前负荷有关发生变化也可以理解?关键是“内存消耗”这一个数据,这个数据是一个绝对的量,代码没有变化,按道理来说应该是没有变化的。很好奇力扣的结果评估机制是什么。

        回到主目录:笨牛慢耕的Leetcode解题笔记(动态更新。。。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨牛慢耕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值