day12-数据结构力扣

一学一个不吱声,以下4道题都是优先掌握递归的方法。

226.翻转二叉树

题目链接226. 翻转二叉树 - 力扣(LeetCode)

优先掌握递归

思路

交换左右子树,但是这里需要注意遍历顺序。

都说简单,其实我看到这个题脑子是空白的,遍历顺序是什么,和这个题有什么关系。怎么交换左右子树

什么是前序?

根 → 左 → 右放到这题里就是:

  1. 先交换当前节点的左右孩子
  2. 再递归翻左子树
  3. 再递归翻右子树

中序顺序是什么?

左 → 根 → 右

放到翻转里就是:

  1. 先翻左子树
  2. 交换当前节点的左右孩子
  3. 再翻右子树

相当于原来的右子树没有处理,而原来的左子树翻了两遍。

所以就是要注意交换,和翻转的一个顺序。

提交

python 复制代码
# 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 invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root==None:
            return root
        root.left,root.right=root.right,root.left
        self.invertTree(root.left)
        self.invertTree(root.right)
        return root

101. 对称二叉树

题目链接 226. 翻转二叉树 - 力扣(LeetCode)

思路

刚开始我想的是对每个根节点翻转左右子树,但是后面发现好像不是,应该是比较外侧节点和内侧节点。

还有个遍历顺序,我之前是从来没有考虑过这个东西的

或者说我其实二叉树类的题目以前都是背题解,里面有很多东西我没有去考虑过为什么

其实听了遍历的讲解,还是模模糊糊的

这道题只能使用"后序遍历",因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等。

递归法的逻辑:

1.确定递归函数的参数和返回值

2.确定终止条件

节点为空的情况有:

  • 左节点为空,右节点不为空,不对称,return false
  • 左不为空,右为空,不对称 return false
  • 左右都为空,对称,返回true

此时已经排除掉了节点为空的情况,那么剩下的就是左右节点不为空:

  • 左右都不为空,比较节点数值,不相同就return false

3.确定单层的递归逻辑

判断左子树的左和右子树的右是否相等,判断左子树的右和右子树的左是否相等

提交

python 复制代码
# 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 isSymmetric(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True
        return self.compare(root.left,root.right)

    def compare(self,left,right):
        if left==None and right!=None:return False
        elif left!=None and right==None:return False
        elif left==None and right==None:return True
        elif left.val!=right.val:return False

        outside=self.compare(left.left,right.right)
        inside=self.compare(left.right,right.left)
        issame=outside and inside
        return issame

104.二叉树的最大深度

题目链接 104. 二叉树的最大深度 - 力扣(LeetCode)

发现day11里面已经写过,只是用的层序遍历。

拓展一下,看看深度和高度的区别

深度(Depth)与高度(Height)的定义

深度:指从根节点到目标节点的路径长度(边数)。根节点的深度为0,每向下一层深度加1。

高度:指从目标节点到最远叶子节点的路径长度(边数)。叶子节点的高度为0,每向上一层高度加1。

示例说明

对于以下二叉树:

复制代码
        A
       / \
      B   C
     / \
    D   E
  • 节点A的深度为0,高度为2(最长路径:A→B→E)。
  • 节点B的深度为1,高度为1(最长路径:B→E)。
  • 节点D的深度为2,高度为0(叶子节点)。

常见误区

  • 混淆深度和高度:深度是相对于根节点的概念,高度是相对于叶子节点的概念。
  • 空树或空节点的高度通常定义为-1,而深度无意义(因无目标节点)。

思路

如果是求高度,需要后序遍历,就是左右中。左右之后,把这个高度给中,然后中把深度加1

如果是求深度,需要前序遍历,就是中左右。中是处理过程,每往下一个就加1

我发现了,好像采用递归方法解题,就需要考虑遍历的顺序。

递归法:

  1. 确定递归函数的参数和返回值:参数就是传入树的根节点,返回就返回这棵树的深度,所以返回值为int类型。

  2. 确定终止条件:如果为空节点的话,就返回0,表示高度为0。

  3. 确定单层递归的逻辑:先求它的左子树的深度,再求右子树的深度,最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)就是目前节点为根节点的树的深度。

提交

python 复制代码
# 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
import collections
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        return self.getdepth(root)

    def getdepth(self,node):
        if not node:
            return 0
        leftdepth=self.getdepth(node.left)
        rightdepth=self.getdepth(node.right)
        return max(leftdepth,rightdepth)+1

111.二叉树的最小深度

题目链接111. 二叉树的最小深度 - 力扣(LeetCode)

思路

是不是和上道题差不多,只是上个取max,我这里取min。试一下

不对

如果这么求的话,没有左孩子的分支会算为最短深度。

所以,如果左子树为空,右子树不为空,说明最小深度是 1 + 右子树的深度。

反之,右子树为空,左子树不为空,最小深度是 1 + 左子树的深度。 最后如果左右子树都不为空,返回左右子树深度最小值 + 1 。

为什么如果左子树为空,右子树不为空,说明最小深度是 1 + 右子树的深度?

  • 必须走到叶子节点才算有效路径

  • 所以只能沿着右子树一直走到叶子

  • 深度就是:当前这一层 (1) + 右子树能走到叶子的最小深度

提交

python 复制代码
# 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 minDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        return self.getdepth(root)

    def getdepth(self,node):
        if not node:
            return 0
        leftdepth=self.getdepth(node.left)
        rightdepth=self.getdepth(node.right)
        if not node.left:
            return rightdepth+1
        elif not node.right:
            return leftdepth+1
        else:
            return min(leftdepth,rightdepth)+1
相关推荐
凌波粒3 小时前
LeetCode--454.四数相加 II(哈希表)
算法·leetcode·散列表
漫随流水3 小时前
c++编程:D进制的A+B(1022-PAT乙级)
数据结构·c++·算法
tankeven4 小时前
HJ159 没挡住洪水
c++·算法
美式请加冰4 小时前
斐波那契数列介绍和使用
算法
paeamecium4 小时前
【PAT】 - Course List for Student (25)
数据结构·c++·算法·pat考试
wen__xvn4 小时前
力扣洛谷模拟题刷题2
算法·leetcode·职场和发展
漫随流水4 小时前
c++编程:说反话(1009-PAT乙级)
数据结构·c++·算法
披着羊皮不是狼5 小时前
深度解构栈内存的物理逻辑与系统保护
数据结构··底层原理
计算机安禾5 小时前
【数据结构与算法】第23篇:树、森林与二叉树的转换
c语言·开发语言·数据结构·c++·线性代数·算法·矩阵