島嶼的個數
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
二叉樹中距離爲K的節點
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<N and q>=0 and q<N:
dp1[i][j] += dp0[p][q]
dp0 = dp1
return dp0[r][c]/(8**K)