岛屿问题
岛屿问题求解的基础知识可参考【LeetCode】200 and 258(DFS解决岛屿问题)。
本文继续从实例出发,熟悉⼆维矩阵的 DFS 代码框架的使用。同时通过实例复习使用快慢指针对链表进行环检测的问题。
1254. 统计封闭岛屿的数目
解法:DFS
根据题意,只有不靠近边界且被水域包围的岛屿才是封闭岛屿。因此该题求解有两个思路:
第一,先遍历边界,将相连的岛屿给淹没。剩下的即为封闭岛屿。
第二,直接遍历,修改判断条件,统计时排除与边界相连的岛屿。
# 解法1
class Solution:
def closedIsland(self, grid: List[List[int]]) -> int:
m, n = len(grid), len(grid[0])
for i in range(m):
# 把靠左边的岛屿淹掉
self.dfs(i, 0, grid)
# 将靠右边的岛屿淹掉
self.dfs(i, n-1, grid)
for j in range(n):
# 将靠上边的岛屿淹掉
self.dfs(0, j, grid)
# 将靠下边的岛屿淹掉
self.dfs(m-1, j, grid)
result = 0
for i in range(m):
for j in range(n):
if grid[i][j] == 0:
self.dfs(i, j, grid)
result += 1
return result
def dfs(self, row, col, grid):
m, n = len(grid), len(grid[0])
if row < 0 or row >= m or col < 0 or col >= n:
return
if grid[row][col] == 1:
return
grid[row][col] = 1
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
for i, j in directions:
self.dfs(row+i, col+j, grid)
# 解法2
class Solution:
def closedIsland(self, grid: List[List[int]]) -> int:
m, n = len(grid), len(grid[0])
result = 0
for i in range(m):
for j in range(n):
# 只统计不与边界相连的岛屿
if grid[i][j] == 0 and self.dfs(i, j, grid):
result += 1
return result
# 从 (i, j) 开始,将与之相邻的陆地都变成海⽔
def dfs(self, row, col, grid):
m, n = len(grid), len(grid[0])
# 若该岛屿与边界相连,则返回False
if row < 0 or row >= m or col < 0 or col >= n:
return False
if grid[row][col] == 1:
return True
# 将陆地淹没
grid[row][col] = 1
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
result = True
# 淹没四个方向的陆地
for i, j in directions:
# 四个方向中任一方向存在与 边界 相连的情况,则该陆地所在岛屿为与边界相连的岛屿,返回False
if not self.dfs(row+i, col+j, grid):
result = False
return result
141. 环形链表
解法:快慢指针
具体地,我们定义两个指针,一快一满。慢指针每次只移动一步,而快指针每次移动两步。初始时,慢指针在位置 head,而快指针在位置 head.next。这样一来,如果在移动的过程中,快指针反过来追上慢指针,就说明该链表为环形链表。否则快指针将到达链表尾部,该链表不为环形链表。
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
seen = set()
while head:
if head in seen:
return True
seen.add(head)
head = head.next
return False