zoukankan      html  css  js  c++  java
  • 【树-03】树的题目解析

    目录

    1. 剑指 Offer 55 - II. 平衡二叉树/110. 平衡二叉树
    2. 剑指 Offer 26. 树的子结构 (中等难度)
    3. 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
    4. 剑指 Offer 68 - II. 二叉树的最近公共祖先/236. 二叉树的最近公共祖先
    5. 剑指 Offer 36. 二叉搜索树与双向链表

    一、剑指 Offer 55 - II. 平衡二叉树/110. 平衡二叉树

    1.1 问题

    输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

    示例 1:

    给定二叉树 [3,9,20,null,null,15,7]

    3

    /

    9 20

    /

    15 7

    返回 true

    1.2 代码

    class Solution:   #注意调用函数时,需要用self,若是嵌套类型的方法定义,则不需要

        def isBalanced(self, root: TreeNode) -> bool:

            if not root :return True

            if (abs(self.height(root.left)-self.height(root.right))>1):

                return False

            else:

                return self.isBalanced(root.left) and self.isBalanced(root.right)

        def height(self,root):

            if not root : return 0

            return 1max(self.height(root.left),self.height(root.right))

       

    二、剑指 Offer 26. 树的子结构 (中等难度)

    2.1 问题

    输入两棵二叉树AB,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

    BA的子结构, 即 A中有出现和B相同的结构和节点值。

       

    例如:

    给定的树 A:

         3

        /

       4   5

      /

     1   2

    给定的树 B

       4 

      /

     1

    返回 true,因为 B A 的一个子树拥有相同的结构和节点值。

       

    示例 1

    输入:A = [1,2,3], B = [3,1]

    输出:false

    示例 2

    输入:A = [3,4,5,1,2], B = [4,1]

    输出:true

    2.2 代码(递归算法)

    class Solution:

        def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:

            def recur(A,B):

                if not B :return True

                if not A  or A.val != B.val :return False

                return recur(A.left,B.left)  and recur(A.right,B.right)

            return bool(A and B) and (recur(A,B) or self.isSubStructure(A.left,B) or self.isSubStructure(A.right,B))

    三、剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

    3.1 问题

    给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

    百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 pq,最近公共祖先表示为一个结点 x,满足 x pq 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。"

    例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5]

    示例 1:

    输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8

    输出: 6

    解释: 节点 2 和节点 8 的最近公共祖先是 6

    示例 2:

    输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4

    输出: 2

    解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

    3.2 代码

    class Solution:

        def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':

            if not root :return None

            if p.val > q.val :  保证 p.val < q.val

                p,q = q,p

            while root :

                if root.val < p.val:  # p,q 都在 root 的右子树中

                    root = root.right    遍历至右子节点

                if root.val > q.val:

                    root = root.left

                else:

                    break

            return root

    四、剑指 Offer 68 - II. 二叉树的最近公共祖先/236. 二叉树的最近公共祖先

    4.1 问题

    给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

    百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 pq,最近公共祖先表示为一个结点 x,满足 x pq 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。"

    例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4]

    示例 1:

    输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1

    输出: 3

    解释: 节点 5 和节点 1 的最近公共祖先是节点 3

    示例 2:

    输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4

    输出: 5

    解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

    4.2 理解

    4.2 代码

    class Solution:

        def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':

            if not root or root == p or root == q: return root  

            left = self.lowestCommonAncestor(root.left, p, q)

            right = self.lowestCommonAncestor(root.right, p, q)

              

            if not left and not right: return # 1.

            if not left: return right # 3.

            if not right: return left # 4.

            return root # 2. if left and right:

    五、剑指 Offer 36. 二叉搜索树与双向链表

    5.1 问题

    输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

    5.2 代码(中序遍历+递归)

    大体思路要清楚:框架是中序遍历,写好中间部分即可:设置两个precurpre若为空,设置下头结点;不空,则进行互相指定。

    不要忘记最后的head与最后的指定。

    """

    # Definition for a Node.

    class Node:

        def __init__(self, val, left=None, right=None):

            self.val = val

            self.left = left

            self.right = right

    """

    class Solution:

        def treeToDoublyList(self, root: 'Node') -> 'Node':

            def dfs(cur):

                if not cur :return

                dfs(cur.left)

                if self.pre:  #不为空,则互相指定

                    self.pre.right,cur.left = cur ,self.pre

                else:  #为空,记录头结点,这个走一遍

                    self.head = cur

                self.pre = cur  #保存后进行下一步推进

                dfs(cur.right)

            if not root :return

            self.pre = None

            dfs(root)

            self.head.left,self.pre.right = self.pre,self.head

            return self.head

    参考文献

    1https://leetcode-cn.com/

  • 相关阅读:
    取模 分数取模 快速幂 费马小定理
    “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛 部份签到题
    shell 脚本
    pyhcl语法
    数据库实验1 SQL
    杂七杂八 Ubuntu Linux
    Kattis, Kattis 的一些问题题解
    Meow Factor 【暴力】
    解决 Eclipse 项目有红感叹号的方法
    RuntimeException与CheckedException
  • 原文地址:https://www.cnblogs.com/yifanrensheng/p/13510832.html
Copyright © 2011-2022 走看看