zoukankan      html  css  js  c++  java
  • 68

    题目:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/submissions/

     写在前面:这一题不同于68-I 二叉搜索树的最近公共祖先https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/(二叉搜索树具有左节点<父节点<右节点的性质),那一题的解决思路以及代码如下:

    # 解题思路 如果要查找的两个节点1.任一个等于根结点值,或者这两个节点指分别位于根节点值的两侧,则返回根节点。2.如果这两个节点只在根节点值的左侧,在左子树查找,3.否则在右子树查找。
    # 注意返回的是节点而非节点的值
    class Solution:
        def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
            if p.val>q.val:
                p,q = q,p
            if p==root or q == root:
                return root
            if p.val<root.val and q.val> root.val:
                return root
            if p.val<root.val and q.val<root.val:
                return self.lowestCommonAncestor(root.left,p,q)
            if p.val>root.val and q.val>root.val:
                return self.lowestCommonAncestor(root.right,p,q)

    针对本题:

    方法一.保存路径形式的思考方式:

    第一种:假设给我们的树中的节点包含一个指向父节点的指针

    如果有了父节点的指针,到达5的逆序路径能得出来为5->4->2->6,到达0的逆序路径为0->2->6由于都有父节点指针,所以这个问题就转换成了求两个链表的第一个公共节点问题;

    第二种:使用数组存储路径

    我们可以使用两个数组保存路径,用先序遍历存储正向路径,如节点5的正向路径为6->2->4->5,节点0的正向路径为6->2->0,从头找到第一个不相同节点的前一个节点即可,这个例子就是指的节点2;

    第二种思路的代码:

    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def lowestCommonAncestor(self, root, p, q):
            """
            :type root: TreeNode
            :type p: TreeNode
            :type q: TreeNode
            :rtype: TreeNode
            """
            stack_1 = []
            stack_2 = []
            def dfs(root, node, stack):
                if not root:
                    return False
                stack.append(root)
                if root.val == node.val:
                    return True          
                if (dfs(root.left, node, stack) or dfs(root.right, node, stack)):
                    return True
                stack.pop()
                
            dfs(root, p, stack_1)
            dfs(root, q, stack_2)
            i = 0
            while i < len(stack_1) and i<len(stack_2) and stack_1[i] == stack_2[i]:
                result = stack_1[i]
                i += 1
            return result

     

    方法二.递归

    【思路】

    因为lowestCommonAncestor(root, p, q)的功能是找出以root为根节点的两个节点p和q的最近公共祖先,所以递归体分三种情况讨论:

    1.如果p和q分别是root的左右节点,那么root就是我们要找的最近公共祖先;

    2.如果p和q都是root的左节点,那么返回lowestCommonAncestor(root.left,p,q);

    3.如果p和q都是root的右节点,那么返回lowestCommonAncestor(root.right,p,q);

    边界条件讨论:

    1.如果root是null,则说明我们已经找到最底了,返回null表示没找到;

    2.如果root与p相等或者与q相等,则返回root;

    3.如果左子树没找到,递归函数返回null,证明p和q同在root的右侧,那么最终的公共祖先就是右子树找到的结点;

    4.如果右子树没找到,递归函数返回null,证明p和q同在root的左侧,那么最终的公共祖先就是左子树找到的结点;

    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def lowestCommonAncestor(self, root, p, q):
            """
            :type root: TreeNode
            :type p: TreeNode
            :type q: TreeNode
            :rtype: 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:
                return right
            if not right:
                return left
            return root

     

  • 相关阅读:
    普通用户权限问题解决:hadoop is not in the sudoers file. This incident will be reported.
    新安装的Ubuntu系统中默认的root用户密码是多少,怎么修改?
    Ubuntu环境变量恢复
    无法获得数据库 'model' 上的排他锁 解决办法
    linux常用命令大全
    Windows 10/Win10命令大全通用(Win8,Win7)
    SQLServer 创建SQL Server 身份验证用户
    SQL注入学习笔记
    vbs整人脚本,别运行!!!
    Linux命令行编辑常用的快捷键
  • 原文地址:https://www.cnblogs.com/USTC-ZCC/p/12547620.html
Copyright © 2011-2022 走看看