leetcode笔记|第十周 DFS

面试题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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值