腾讯精选45(共同祖先)--python

# 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
        """
        def f(node,aim):
            stack=[]
            while node or stack:
                if node:
                    if node==aim:
                        return True
                    stack.append(node)
                    node=node.left
                else:
                    n=stack.pop()
                    node=n.right
            else:
                return False
            
        if not root or root==p or root==q:
            return root
        stack=[]
        re=root
        while stack or re:
            if re:
                stack.append(re)
                if re==p or re==q:
                    break
                re=re.left
            else:
                node=stack.pop()
                re=node.right
        new=q if re==p else p
        while stack:
            a=stack.pop()
            if f(a,new):
                return a        

搞了一下午终于算搞出来了,看题解发现看不懂,比葫芦画瓢也总是出现各种各样的问题,不如自己想个办法
在这里插入图片描述
通过中序遍历法,当发现p或q(假设为p)时break,然后全力找q。
其中有个秘诀就是break时其中的stack中的元素均为p的祖先且若存在pq的共同祖先必存在于stack中,我编写了一个新函数来判断q是否是某节点的子孙,对stack中从后向前依次判断即可
本思路的难点在于:为什么break时共同祖先一定在stack中,stack中并不包含p所有祖先,譬如若p不是一直处于二叉树的最左边,那么定会在是stack.pop()后右面,那么pop后就会丢掉p的一个祖先,但要理解这个祖先一定不是他们的共同祖先,因为这个祖先的左面是不存在p或q的,所以就算他是共同祖先也绝对不是深度最深的,所以可以排除

在这里插入图片描述
多调试了几次,执行用时基本控制在40-60ms,内存稳定在19.7或19.8MB,击败用户执行用时稳定98%以上,击败用户内存消耗稳定在97%-98%
其实本思路还可以继续优化,因为stack中除了p的左右面没有测过,其余的元素的左面都已经测试过了,所以把p单独拿出来测,其余的元素可以只测试右面,代码如下:

# 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
        """
        def f(node,aim):
            stack=[]
            while node or stack:
                if node:
                    if node==aim:
                        return True
                    stack.append(node)
                    node=node.left
                else:
                    n=stack.pop()
                    node=n.right
            else:
                return False
            
        if not root or root==p or root==q:
            return root
        stack=[]
        re=root
        while stack or re:
            if re:
                if re==p or re==q:
                    break
                stack.append(re)
                re=re.left
            else:
                node=stack.pop()
                re=node.right
        new=q if re==p else p
        if f(re,new):
            return re
        while stack:
            a=stack.pop()
            if f(a.right,new):
                return a        

思路其实只是小小优化,相信对速度的影响不会太大,但绝对简化了代码,减小了服务器的工作量,但如果多次使用程序的话还是会出现效果的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值