LeetCode每日一题(11)——太平洋大西洋水流问题(递归,深度优先遍历实例)

简介: 大西洋太平洋水流问题1.题目2.示例3.思路理解题目解题思路4.代码

1.题目


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


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


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


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


2.示例


3.jpg


示例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] <= 105


3.思路


理解题目


这个题目说的不清楚,压根就没有提到既能流到太平洋又能流到大西洋


0.png


点击力扣问题的这个位置可以查看英文题目,很容易发现,题目的的both并没有被中文版的问题描述出来

英文版对返回值的要求如下:


1.png


解题思路


判断水流到下一个位置以后的流动情况和判断水在当前位置的流动情况方法相同,很自然的想到可以采用递归调用的方法进行深度优先遍历。

①以数组的每一个位置为起点,流入海洋或者无处可流为终点

②从外围每一个流入海洋的位置为起点,到能走的最高点(等高还是要走)为终点

感觉②会好一点点


4.代码


//新建四个数组的切片,后面遍历以访问四个方向
var dirs = []struct{ x, y int }{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}
func pacificAtlantic(heights [][]int) (ans [][]int) {
  //生成合适大小的二维数组,用来分别储存太平洋的位置和大西洋的位置
  m, n := len(heights), len(heights[0])
  //太平洋
  pacific := make([][]bool, m)
  //大西洋
  atlantic := make([][]bool, m)
  //初始化二维数组,全部赋值为false
  for i := range pacific {
    pacific[i] = make([]bool, n)
    atlantic[i] = make([]bool, n)
  }
  log.Println(pacific)
  log.Println(atlantic)
  //定义递归方法,参数为当前的位置坐标和某个大洋的是否可达二维数组
  var dfs func(int, int, [][]bool)
  dfs = func(x, y int, ocean [][]bool) {
    //已经被访问过,直接返回
    if ocean[x][y] {
      return
    }
    //将没有访问过更改为访问过
    ocean[x][y] = true
    //向四个方向延伸
    for _, d := range dirs {
      //如果满足要求(下一个单元格不超出长度限制,高度大于当前高度,则继续向下搜索)
      if nx, ny := x+d.x, y+d.y; 0 <= nx && nx < m && 0 <= ny && ny < n && heights[nx][ny] >= heights[x][y] {
        //递归调用
        dfs(nx, ny, ocean)
      }
    }
  }
  //左侧起点
  for i := 0; i < m; i++ {
    dfs(i, 0, pacific)
  }
  //上方起点
  for j := 1; j < n; j++ {
    dfs(0, j, pacific)
  }
  //右侧起点
  for i := 0; i < m; i++ {
    dfs(i, n-1, atlantic)
  }
  //下方起点
  for j := 0; j < n-1; j++ {
    dfs(m-1, j, atlantic)
  }
  //最后遍历任意一个大洋的结果集,如果与另一个大洋对应位置都是true,则添加该位置到最终的结果集中
  for i, row := range pacific {
    for j, ok := range row {
      if ok && atlantic[i][j] {
        ans = append(ans, []int{i, j})
      }
    }
  }
  return
}
相关文章
|
3天前
|
算法 Java
LeetCode第94题二叉树的中序遍历
文章介绍了LeetCode第94题"二叉树的中序遍历"的解法,使用递归实现了中序遍历的过程,遵循了"左根右"的遍历顺序,并提供了清晰的Java代码实现。
LeetCode第94题二叉树的中序遍历
|
4天前
|
存储
LeetCode------递归(爬楼梯)
这篇文章通过LeetCode上的"爬楼梯"问题介绍了递归的基本概念和实现方法,包括递归公式的推导、基本递归实现、使用备忘录优化以避免重复计算,以及自底向上的迭代方法来提高效率。
LeetCode------递归(爬楼梯)
|
12天前
|
算法 Python
【Leetcode刷题Python】剑指 Offer 33. 二叉搜索树的后序遍历序列
本文提供了一种Python算法,用以判断给定整数数组是否为某二叉搜索树的后序遍历结果,通过识别根节点并递归验证左右子树的值是否满足二叉搜索树的性质。
11 3
|
13天前
|
Python
【Leetcode刷题Python】105. 从前序与中序遍历序列构造二叉树
LeetCode上105号问题"从前序与中序遍历序列构造二叉树"的Python实现,通过递归方法根据前序和中序遍历序列重建二叉树。
12 3
|
13天前
|
Python
【Leetcode刷题Python】145. 二叉树的后序遍历
LeetCode上145号问题"二叉树的后序遍历"的Python实现方法。
13 2
|
13天前
|
Python
【Leetcode刷题Python】144. 二叉树的前序遍历
LeetCode上144号问题"二叉树的前序遍历"的Python实现方法。
12 1
|
10天前
|
存储 算法 Java
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
29 0
|
13天前
|
Python
【Leetcode刷题Python】94. 二叉树的中序遍历
LeetCode上94号问题"二叉树的中序遍历"的Python实现方法。
7 0
|
12天前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
26 6
|
12天前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
39 2