leetcode_二叉树相关题目(1)----Python

前言

二叉树数据结构里还挺常用的,但是都快忘记了,就来刷一下题回顾一下,顺便还能练练python

二叉树的最大深度

题目

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

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

    3
   / \
  9  20
    /  \
   15   7

返回它的最大深度 3

分析

二叉树的深度倒还真记得是什么东西,从示例来看,貌似节点是一层一层铺上去的

解法1—迭代

这种方法,写起来比较省事省心,很精巧,看代码应该看得懂,把每层的节点都当作根节点计算一次,如果读到空就将层数加1后返还

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if root is None:
            return 0
        else:
            right_height = self.maxDepth(root.right)
            left_height = self.maxDepth(root.left)
            return max(left_height, right_height) + 1

解法2—DFS

深度遍历算法是个啥其实我已经忘记了233,百度一下

深度优先遍历(DFS);

1、访问指定的起始顶点;

2、若当前访问的顶点的邻接顶点有未被访问的,则任选一个访问之;反之,退回到最近访问过的顶点;直到与起始顶点相通的全部顶点都访问完毕;

3、若此时图中尚有顶点未被访问,则再选其中一个顶点作为起始顶点并访问之,转 2; 反之,遍历结束。

当然这是图的情况,如果是连通图的话就和二叉树有点类似了,一开始用一个list或者dict存储各个节点是否被访问过的状态是不错的选择

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        stack = []
        if root is not None:
            stack.append((1,root))  # 若根节点非空,则压入
        depth = 0
        while stack !=[]:
            current_depth, root = stack.pop()
            if root is not None:
                depth = max(depth, current_depth)
                stack.append((current_depth + 1, root.left))
                stack.append((current_depth + 1, root.right))
        return depth

因为二叉树肯定是连通的,其实就是每个节点不断地向左右衍生直到尽头,这么想像,其实和迭代也是很相似的,只不过他是把所有的深度进行比较,而迭代则是把左右节点中的最大深度选择一个大的

二叉搜索树的最近公共祖先

什么是二叉搜索树

一开始看到这个名字有点懵,查了下概念,逐渐有了印象

二叉搜索树,又称二叉排序树。它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉搜索树。

题目

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

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

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

img

示例 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, 因为根据定义最近公共祖先节点可以为节点本身。

说明:

  • 所有节点的值都是唯一的。
  • p、q 为不同节点且均存在于给定的二叉搜索树中。

分析

好在说明里说了节点是唯一的,也比较贴近生活,生活中完完全全一样的东西肯定还是少的,但肯定也有局限性,统计数字之类就不是很好办,比如考试同分,但这就不满足儿茶搜索树的定义了,反正先把简单的弄懂再说

解题

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        if q.val >= root.val >= p.val or q.val <= root.val <=p.val:
            return root
        elif q.val > root.val and p.val > root.val:
            return self.lowestCommonAncestor(root.right,p,q)
        elif q.val < root.val and p.val < root.val:
            return self.lowestCommonAncestor(root.left,p,q)
        else:
            return None

其实理解了最基本的迭代的话还是比较轻松的,目的就是不断地把输入的p,q两个节点放在某一个节点的两侧,达成这个目的就好,函数内部调用自身不要忘记self就好

二叉树的最近公共祖先

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

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

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

img

示例 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。因为根据定义最近公共祖先节点可以为节点本身。

分析

没有排序,不能无脑迭代了,要稍微想一想,题目难度从简单一下变成了中等,中等难度的,不看答案的话,目前而言我写不出正确以及优雅的代码,难受

解题

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        if not root or p == root or q == root:
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if left == None:
            return right
        if right == None:
            return left
        return root

这个迭代比上一个感觉难理解一些,大概就是遍历,如果返还的左右子树都有值,那么最近公共祖先就在根节点上,但如果有一边的子树没有返回值,那最近祖先就一定在另一边的子树上

Hexo链接:https://woaixiaoyuyu.github.io/2019/02/07/leetcode-二叉树相关题目/#more

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值