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

搜索 · 08-08

题目链接:https://leetcode.cn/problems/pacific-atlantic-water-flow/description/

我的思路

看了一下提示,采用逆向DFS的方法,与其直接看某个点是否能同时流向两个海洋,不如直接从四个边出发,能“逆流而上”,说明这个点能够流向对应的海洋,且从四条边出发也能很好分辨两个海洋,分别设定两个矩阵,最后取两个矩阵都为1的公共部分作为答案即可

但是在实现上面的步骤时遇到一个坑,还是对python的变量定义内部原理不是很清晰,知道要用两个矩阵来表示某个点是否能流向对应的洋,于是乎直接定义is_p = [[0] * n] * m ,这样实际上里每一行都是同一个对象的引用,在修改 is_p[x][y] 的时候,会导致这一列在所有行都被修改,所以DFS标记访问的时候,访问一行等于整列都变化,结果乱掉,称为浅拷贝陷阱

纠正

  1. 采用is_p = [[0] * n for _ in range(m)] 的形式定义初始化矩阵,能够保证每个元素都是独立的变量,在修改时不会一整块都被修改了

反思

  1. 用好反向思维:题目要求的是满足向下流能到达两个大洋的位置,如果我们对所有的位置进行搜索,那么在不剪枝的情况下复杂度会很高。因此我们可以反过来想,从两个大洋开始向上流,这样我们只需要对矩形四条边进行搜索
  2. 浅拷贝问题:

    1. Python 变量:名字 → 对象(引用关系)
    2. =:拷贝的是引用
    3. 浅拷贝:拷贝容器本身,但里面的引用不变(常见 bug 来源)
    4. 深拷贝:完全递归复制,最安全
    5. 避免浅拷贝 bug:二维数组初始化:用列表推导式,对象拷贝:用 deepcopy,一维简单拷贝:切片 / list()

结果

时间复杂度:$O(mn)$

空间复杂度:$O(mn)$

已是最优解