题目链接:https://leetcode.cn/problems/pacific-atlantic-water-flow/description/
我的思路
看了一下提示,采用逆向DFS的方法,与其直接看某个点是否能同时流向两个海洋,不如直接从四个边出发,能“逆流而上”,说明这个点能够流向对应的海洋,且从四条边出发也能很好分辨两个海洋,分别设定两个矩阵,最后取两个矩阵都为1的公共部分作为答案即可
但是在实现上面的步骤时遇到一个坑,还是对python的变量定义内部原理不是很清晰,知道要用两个矩阵来表示某个点是否能流向对应的洋,于是乎直接定义is_p = [[0] * n] * m
,这样实际上里每一行都是同一个对象的引用,在修改 is_p[x][y]
的时候,会导致这一列在所有行都被修改,所以DFS标记访问的时候,访问一行等于整列都变化,结果乱掉,称为浅拷贝陷阱
纠正
- 采用
is_p = [[0] * n for _ in range(m)]
的形式定义初始化矩阵,能够保证每个元素都是独立的变量,在修改时不会一整块都被修改了
反思
- 用好反向思维:题目要求的是满足向下流能到达两个大洋的位置,如果我们对所有的位置进行搜索,那么在不剪枝的情况下复杂度会很高。因此我们可以反过来想,从两个大洋开始向上流,这样我们只需要对矩形四条边进行搜索
浅拷贝问题:
- Python 变量:名字 → 对象(引用关系)
- =:拷贝的是引用
- 浅拷贝:拷贝容器本身,但里面的引用不变(常见 bug 来源)
- 深拷贝:完全递归复制,最安全
- 避免浅拷贝 bug:二维数组初始化:用列表推导式,对象拷贝:用 deepcopy,一维简单拷贝:切片 / list()
结果
时间复杂度:$O(mn)$
空间复杂度:$O(mn)$
已是最优解