面试题04.04 检查平衡性
二叉树任何一个节点的两棵子树的高度相差不大于1,叫做平衡数。
class Solution:
def Depth(self,root): # 判断子树高度差
if not root:
return 0
return 1 + max(self.Depth(root.left), self.Depth(root.right))
def isBalanced(self, root: TreeNode) -> bool:
if not root:
return True # 没有左右子树肯定是平衡树了
if abs(self.Depth(root.left) - self.Depth(root.right)) > 1:
return False
return self.isBalanced(root.left) and self.isBalanced(root.right) # 左右子树都是平衡树
257 二叉树的所有路径
输出: [“1->2->5”, “1->3”] 解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3
class Solution:
def binaryTreePaths(self, root: TreeNode) -> List[str]:
def calculate_path(root, path):
if root:
path += str(root.val)
if not root.left and not root.right: # 叶子节点,直接输出
paths.append(path)
else: # 非叶子节点,迭代
path += '->'
calculate_path(root.left, path)
calculate_path(root.right, path)
paths = []
calculate_path(root, '')
return paths
面试题16.19 水域大小
输入:
[
[0,2,1,0],
[0,1,0,1],
[1,1,0,1],
[0,1,0,1]
]
输出: [1,2,4] 解释:0的地方是水池,不为0的是陆地,连在一起的0形成水域,计算水域大小,排序输出。
class Solution:
def pondSizes(self, land: List[List[int]]) -> List[int]:
res = []
m,n = len(land), len(land[0])
def calculate_water(i,j):
land[i][j]=1 # 找过的水池要填上,然后遍历周围八个,每个为0又可以遍历周围八个
size = 1
for (x,y) in [(i+1,j),(i-1,j),(i,j+1),(i,j-1),(i-1,j-1),(i-1,j+1),(i+1,j-1),(i+1,j+1)]:
if x>=0 and x<m and y>=0 and y<n and land[x][y]==0:
size += calculate_water(x,y)
return size
for i in range(m): # 迭代矩阵的每个元素,找0的地方,计算水域大小后放入res
for j in range(n):
if land[i][j]==0:
res.append(calculate_water(i,j))
res.sort()
return res
106 从中序与后序遍历序列构造二叉树
前序遍历根左右 中序遍历左根右 后序遍历左右根
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
# 四个元素分别是树的inorder的左右边界,postorder的左右边界
def buildRoot(in_left, in_right, post_left, post_right):
if in_left>in_right:
return
# postorder最后一个就是root.val==post_root==in_root
post_root = post_right
root = TreeNode(postorder[post_root])
in_root = inorder_map[root.val]
# 左子树的长度可以计算:
length_left_tree = in_root - in_left
# 迭代左右子树
root.left = buildRoot(in_left,in_root-1,post_left,post_left+length_left_tree-1)
root.right = buildRoot(in_root+1,in_right,post_left+length_left_tree,post_root-1)
return root
if not inorder:
return None
# inorder_map: { ele: idx } 由根节点元素确定在inorder中的idx,使用字典,时间为常数,用空间换时间
n = len(inorder)
inorder_map = {}
for i in range(n):
inorder_map[inorder[i]]=i
return buildRoot(0,n-1,0,n-1)
200 岛屿数量
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
def cal_grid(grid,i,j):
queue=[[i,j]]
while queue: # 探索周围四个范围
[x,y] = queue.pop(0)
if 0<=x<m and 0<=y<n and grid[x][y]=='1':
grid[x][y]='0'
queue += [[x-1,y],[x+1,y],[x,y-1],[x,y+1]]
res = 0
m,n=len(grid),len(grid[0])
if m==0 or n==0:
return 0
for i in range(m):
for j in range(n):
if grid[i][j]=="0":continue # 节省时间
cal_grid(grid,i,j)
res += 1
return res
1254 统计封闭岛屿的数目
class Solution:
def closedIsland(self, grid: List[List[int]]) -> int:
# 寻找被1包围的0,如果在边缘的0那么可以处理为1
def fengbi(i,j):
# 边界为1时return省时间
if grid[i][j]==1:
return
# 遇到0处理为1直至没有0自动退出
grid[i][j]=1
for (x,y) in [(i-1,j),(i+1,j),(i,j-1),(i,j+1)]:
if 0<=x<m and 0<=y<n and grid[x][y]==0:
fengbi(x,y)
res = 0
m, n = len(grid), len(grid[0])
if m==0 or n==0:
return 0
for i in range(m):
fengbi(i,0)
fengbi(i,n-1)
for j in range(n):
fengbi(0,j)
fengbi(m-1,j)
for i in range(m):
for j in range(n):
if grid[i][j]==0:
# 遇到0的一整片区域算作一次封闭水域,因为边界已经被处理过了
fengbi(i,j)
res+=1
return res
827 最大人工岛
class Solution:
def largestIsland(self, grid: List[List[int]]) -> int:
# DFS 超时:遍历0,如果改为1,则这一块陆地的面积是多少,最终取最大陆地面积
# 记录每块土地对应的岛屿大小,遍历海洋周围陆地的岛屿大小和
def cal_area(i,j,index):
area = 1
grid[i][j]=index # 将陆地用岛屿编号赋值
for (x,y) in [(i-1,j),(i+1,j),(i,j-1),(i,j+1)]:
if 0<=x<N and 0<=y<N and grid[x][y]==1:
area += cal_area(x,y,index) # 计算岛屿的面积
return area
# 将能够连同的陆地也就是岛屿进行编号,记录编号对应的岛屿面积
idx2area = {}
idx2area[0]=0
N = len(grid)
index = 2
for i in range(N):
for j in range(N):
if grid[i][j]==1:
idx2area[index]=cal_area(i,j,index)
index += 1
res = 0
for i in range(N):
for j in range(N):
if grid[i][j]==0:
seen = {grid[x][y] for (x,y) in [(i-1,j),(i+1,j),(i,j-1),(i,j+1)] if 0<=x<N and 0<=y<N}
res = max(res, 1+sum(idx2area[i] for i in seen)) # 找到海洋,计算周围岛屿面积和+这块陆地的1
return res if res!=0 else N*N # 如果res=0说明没有海洋全是陆地因此返回N*N