边工作边刷题:70天一遍leetcode: day 60
Lowest Common Ancestor of a Binary Tree
要点:这题和Binary Search Tree的版本递归都很简单,问题是如何用iteration来做。BST比较简单,直接沿一条分支搜索即可。而Binary Tree需要用post-order traversal的方法,开始想的时候试了几条路都不对,最终还是想出来了。以下为思考过程:
- 开始想maintain一个global的left和right来标记左右子树中,但用global是不对的,left和right都是局部于子树的。
- 并且如果向下展开时候遇到p或者q,可不可以提早回溯呢?答案显然是不能,因为另一个还没找到,要继续遍历
- 然后想把左右存在stack中,其实没必要存2个,只需要存子树中结点出现的count的就可以
- 但是stack是不行的,因为在访问后就pop了,无法根据left,right的值得到当前结点的count
- 最终可行的是用map存结点count,而不是在stack里,类似Balanced Binary Tree
# 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: return None
stk = [root]
hmap = {}
pre = None
while stk:
cur = stk[-1]
if pre==None or pre.left==cur or pre.right==cur:
if cur.left:
stk.append(cur.left)
elif cur.right:
stk.append(cur.right)
elif cur.left==pre:
if cur.right:
stk.append(cur.right)
else:
count = 0
if cur.left:
count+=hmap[cur.left]
if cur.right:
count+=hmap[cur.right]
if cur==p or cur==q:
count+=1
if count==2:
return cur
hmap[cur]=count
stk.pop()
pre = cur
return None