剑指 Offer II 105. 岛屿的最大面积
比较简单的一道题,和之前那个求岛屿数量的差不多,都是同样的递归,但是求最大面积需要记录每隔岛屿的面积,然后求最大。这里递归有两种写法。本质上差不多。
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
# 和200岛屿数量差不多,这次只需要没遇到一个1,就在淹没它的同时,记录它的大小。最后取max操作
m, n = len(grid), len(grid[0])
res = 0
for i in range(m):
for j in range(n):
if grid[i][j] == 0: continue
area = self.dfs(grid, i, j, 0)
res = max(res, area)
return res
def dfs(self, grid, i, j, area):
# 淹没当前陆地同时计算大小
if i < 0 or i >= len(grid) or j < 0 or j >= len(grid[0]):
return 0
if grid[i][j] == 0: return 0
grid[i][j] = 0 # 淹没土地
area = 1
up = self.dfs(grid, i-1, j, area)
down = self.dfs(grid, i+1, j, area)
left = self.dfs(grid, i, j-1, area)
right = self.dfs(grid, i, j+1, area)
return area + up + left + right + down
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
# 和200岛屿数量差不多,这次只需要没遇到一个1,就在淹没它的同时,记录它的大小。最后取max操作
m, n = len(grid), len(grid[0])
res = 0
for i in range(m):
for j in range(n):
if grid[i][j] == 0: continue
area = self.dfs(grid, i, j)
res = max(res, area)
return res
def dfs(self, grid, i, j):
# 淹没当前陆地同时计算大小
if i < 0 or i >= len(grid) or j < 0 or j >= len(grid[0]):
return 0
if grid[i][j] == 0: return 0
grid[i][j] = 0 # 淹没土地
area = 1
for (di, dj) in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
next_i, next_j = i + di, j + dj
area += self.dfs(grid, next_i, next_j)
# up = self.dfs(grid, i-1, j, area)
# down = self.dfs(grid, i+1, j, area)
# left = self.dfs(grid, i, j-1, area)
# right = self.dfs(grid, i, j+1, area)
return area
114. 二叉树展开为链表
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
# 那就先序遍历呗
nums = []
def backtrack(root):
if not root: return
nums.append(root.val)
backtrack(root.left)
backtrack(root.right)
backtrack(root)
# 有了nums数组之后,开始对树进行修改
# 因为只要根节点不动,就不会影响结果。所以就把他当作一个root开头的链表,每次往后面追加一个新节点就完了。不需要考虑树的插入什么的。
i = 1
for i in range(1, len(nums)):
if root.left:
root.left = None
root.right = TreeNode(nums[i])
root = root.right
113. 路径总和 II
其实就是一道回溯题。本来没想着一下子做出来,结果按照模板一下子直接AC了。😊
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
# 其实也是回溯
res = []
path = []
def dfs(root, target_sum):
if not root: return
path.append(root.val)
target_sum -= root.val
# root是叶子节点,而且路径和等于目标值
if not root.left and not root.right and target_sum == 0:
res.append(path[:])
dfs(root.left, target_sum)
dfs(root.right, target_sum)
path.pop() # 撤销
dfs(root, targetSum)
return res
129. 求根节点到叶节点数字之和
还是回溯,不过这里注意,python中数字和字符串是不可变的,如果像上一题一样,把res和path作为全局变量,会出现局部变量未声明直接调用的bug。所以这里把path作为参数传入dfs函数,同时res也选择list来保存每一个数字,而不是直接加。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sumNumbers(self, root: TreeNode) -> int:
# 应该也可以使用回溯
res = []
path = '' # 字符串和list不一样,是不可变的,所以不能直接作为全局变量让dfs函数调用
def dfs(root, path):
if not root:
return
path = path + str(root.val)
# 到了叶子节点
if not root.left and not root.right:
# res += int(path)
res.append(int(path))
dfs(root.left, path)
dfs(root.right, path)
path = path[:-1] # 撤销
dfs(root, path)
return sum(res)