leetcode 200. 岛屿的个数: https://leetcode-cn.com/problems/number-of-islands/
思路: DFS,走过一个要改成-1。
class Solution:
def numIslands(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
if len(grid) == 0:
return 0
m = len(grid)
n = len(grid[0])
res = 0
for i in range(m):
for j in range(n):
if grid[i][j] == '1':
res += 1
self.dfs(grid, i, j)
return res
def dfs(self,grid,i,j):
grid[i][j] = '-1'
orients = [[-1, 0], [1, 0], [0, -1], [0, 1]]
for o in orients:
p = i + o[0]
q = j + o[1]
if p >= 0 and q >= 0 and p < len(grid) and q < len(grid[0]) and grid[p][q] == '1':
self.dfs(grid, p, q)
return
leetcode 695 岛屿最大面积:https://leetcode-cn.com/problems/max-area-of-island/submissions/
class Solution:
def maxAreaOfIsland(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
if len(grid) == 0:
return 0
m = len(grid)
n = len(grid[0])
res = 0
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
area = self.dfs(grid, i, j)
res = max(res, area)
return res
def dfs(self, grid, i, j):
area = 1
grid[i][j] = -1 #表示已经走过
orients = [[-1,0],[1,0],[0,-1],[0,1]]
for o in orients:
p = i + o[0]
q = j + o[1]
if p>= 0 and q >= 0 and p < len(grid) and q < len(grid[0]) and grid[p][q] == 1:
area += self.dfs(grid,p,q)
return area
leetcode 130 被围绕的区域:https://leetcode-cn.com/problems/surrounded-regions/
首先对边界上每一个'O'做深度优先搜索,将与其相连的所有'O'改为'-'。然后遍历矩阵,将矩阵中所有'O'改为'X',将矩阵中所有'-'变为'O'
class Solution:
def solve(self, board):
"""
:type board: List[List[str]]
:rtype: void Do not return anything, modify board in-place instead.
"""
if len(board) == 0:
return
m = len(board)
n = len(board[0])
#先把边界上的连通的O都刨去(变成-)
for i in range(m):
self.dfs(board, i, 0)
self.dfs(board, i, n-1)
for j in range(n):
self.dfs(board, 0, j)
self.dfs(board, m-1, j)
#剩下的O肯定被X包围,将其变为X,最后记得把上面变成-的O再变回去
for i in range(m):
for j in range(n):
if board[i][j] == 'O':
board[i][j] = 'X'
elif board[i][j] == '-':
board[i][j] = 'O'
return
def dfs(self, board, i, j):
if i >= 0 and j >= 0 and i < len(board) and j < len(board[0]) and board[i][j] == 'O':
board[i][j] = '-'
orients = [(-1,0), (1,0), (0,-1),(0,1)]
for o in orients:
p = i + o[0]
q = j + o[1]
self.dfs(board, p, q)
return
leetcode 417. 太平洋大西洋水流问题:https://leetcode-cn.com/problems/pacific-atlantic-water-flow/
建立两个矩阵Atlantic和Pacific, 当Atlantic[i][j]和Pacific[i][j]同时为true时表示该位置可以同时到达Atlantic和Pacific
便历时的技巧为: 只需要从四个边界开始遍历即可(类似泛洪的思想, 只要可以从边界出发到达, 就说明该位置的水可以流向对应的海洋)
class Solution(object):
def pacificAtlantic(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[List[int]]
"""
#即找到边界是否能连通到哪些位置即可
if len(matrix) == 0:
return []
m = len(matrix)
n = len(matrix[0])
pacific = [[False for _ in range(n)] for _ in range(m)]
atlantic = [[False for _ in range(n)] for _ in range(m)]
for i in range(m):
self.dfs(matrix, i, 0, pacific, matrix[i][0])
self.dfs(matrix, i, n-1, atlantic, matrix[i][n-1])
for j in range(n):
self.dfs(matrix, 0, j, pacific, matrix[0][j])
self.dfs(matrix, m-1, j, atlantic, matrix[m-1][j])
res = []
for i in range(m):
for j in range(n):
if pacific[i][j] and atlantic[i][j]:
res.append([i,j])
return res
def dfs(self, matrix, i, j, visited, pre):
if i >= 0 and i < len(matrix) and j >= 0 and j < len(matrix[0]) and (not visited[i][j]) and matrix[i][j] >= pre:
visited[i][j] = True
self.dfs(matrix, i-1, j, visited, matrix[i][j])
self.dfs(matrix, i+1, j, visited, matrix[i][j])
self.dfs(matrix, i, j-1, visited, matrix[i][j])
self.dfs(matrix, i, j+1, visited, matrix[i][j])
return
leetcode 529 扫雷:https://leetcode-cn.com/problems/minesweeper/
class Solution(object):
def updateBoard(self, board, click):
"""
:type board: List[List[str]]
:type click: List[int]
:rtype: List[List[str]]
"""
if len(board) == 0:
return []
m = len(board)
n = len(board[0])
#先实现标记一下哪些点周围有地雷
orients = [(-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (-1, 1), (1, -1), (1, 1)]
visited = [[False for _ in range(n)] for _ in range(m)]#标记是否访问过
nums = [[0 for _ in range(n)] for _ in range(m)]#标记每个点周围地雷的个数
for i in range(m):
for j in range(n):
if board[i][j] == 'M':
for x, y in orients:
if i+x >= 0 and i+x < m and j+y >=0 and j+y < n:
nums[i+x][j+y] += 1
self.dfs(board, click[0], click[1], nums, orients, visited)
return board
def dfs(self, board, i, j, nums, orients, visited):
visited[i][j] = True
if board[i][j] == 'M':
board[i][j] = 'X'
return
if nums[i][j] > 0:
board[i][j] = str(nums[i][j])
return
if board[i][j] == 'E':
board[i][j] = 'B'
for x, y in orients:
if i+x >= 0 and i+x < len(board) and j+y >=0 and j+y < len(board[0]) and not visited[i+x][j+y]:
self.dfs(board, i+x, j+y, nums, orients, visited)
return
leetcode 863 二叉树中所有距离为K的节点:https://leetcode-cn.com/problems/all-nodes-distance-k-in-binary-tree/comments/
建图 + DFS
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
from collections import defaultdict
class Solution:
def distanceK(self, root, target, K):
"""
:type root: TreeNode
:type target: TreeNode
:type K: int
:rtype: List[int]
"""
if root is None:
return []
res = []
g = defaultdict(list)
self.buildGraph(None, root, g)#创建图
visited = [target]#保存访问过的节点
self.dfs(target, 0, K, res, visited, g)
return res
def buildGraph(self, parent, child, g):
if parent:
g[parent].append(child)
g[child].append(parent)
if child.left:
self.buildGraph(child, child.left,g)
if child.right:
self.buildGraph(child, child.right,g)
def dfs(self, start, i, K, res, visited, g):
if start is None:
return
if i > K:
return
if i == K:
res.append(start.val)
return
for node in g[start]:
if node in visited:
continue
visited.append(node)
self.dfs(node, i+1, K, res, visited, g)
https://leetcode-cn.com/problems/knight-probability-in-chessboard/submissions/
class Solution:
def knightProbability(self, N, K, r, c):
"""
:type N: int
:type K: int
:type r: int
:type c: int
:rtype: float
"""
cnt = 0
dp0 = [[1 for i in range(N)] for j in range(N)]#代表每个位置可以由多少个点走k步到达
orients = [(1,2),(1,-2),(-1,2),(-1,-2),(2,1),(2,-1),(-2,1),(-2,-1)]
for _ in range(K):
dp1 = [[0 for i in range(N)] for j in range(N)]
for i in range(N):
for j in range(N):
for x,y in orients:
p = i + x
q = j + y
if p>=0 and p=0 and q