leetcode--Lowest Common Ancestor of a Binary Tree--ポイント
7111 ワード
https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/
ここはBTです。BSTではありません。考えはrootからpとqのパスを見つけて最後の交点を見つけます。どのようにfind Pathに注意しますか?
再帰をどう使うかhttp://bookshadow.com/weblog/2015/07/13/leetcode-lowest-common-ancestor-binary-tree/
考え方1 findPath。post-orderを使う
ここはBTです。BSTではありません。考えはrootからpとqのパスを見つけて最後の交点を見つけます。どのようにfind Pathに注意しますか?
再帰をどう使うかhttp://bookshadow.com/weblog/2015/07/13/leetcode-lowest-common-ancestor-binary-tree/
考え方1 findPath。post-orderを使う
class Solution(object):
def findPath(self, root, target):
stack = []
pre = None
while stack or root:
if root:
stack.append(root)
root = root.left
else:# post order。 , , root,scan root path
peek = stack[-1]# the first value of peek should be the most left node
if peek.right and pre != peek.right:
root = peek.right# , pop , pop
else:# , 。
if peek == target:
return stack
pre = stack.pop()
root = None #
def lowestCommonAncestor(self, root, p, q):
""" :type root: TreeNode :type p: TreeNode :type q: TreeNode :rtype: TreeNode """
path1 = self.findPath(root, p)
path2 = self.findPath(root, q)
i = 0
len1, len2 = len(path1), len(path2)
while i < min(len1, len2) and path1[i] == path2[i] :
i += 1
i -= 1
return path1[i]
ここではpreorderでstackのコードを直接持ってはいけません。pushのelementでstackに入れた後、探しているnodeかどうかを判断します。反例[2,null,1]は、1にとって最後のパスの結果は1だけです。したがって、次のようなパスのコードは正しくありません。上のコードを覚えてください。 while stack or root:
if root:
stack.append(root)
if root == target:
return stack
root = root.left
else:
root = stack.pop()
root = root.right
考え方2再帰class Solution(object):
def lowestCommonAncestor(self, root, p, q):
""" :type root: TreeNode :type p: TreeNode :type q: TreeNode :rtype: TreeNode """
# if root == None return root if root == None :return None
if root == None or root == p or root == q:
return root
# divide
left = self.lowestCommonAncestor(root.left, p, q)# p,q LCA
right = self.lowestCommonAncestor(root.right, p, q)# p,q LCA
# conquer # right None p q root.right LCA, node node 。
if left and right:# None, LCA, LCA, LCA root
return root
elif left:
return left
elif right:
return right
else:
return None
findPath-postorderを自分で書き直します。 def findPath(self, root, target):
stack = []
last = None
while stack or root:
if root:
stack.append(root.val)
#last = root
root = root.left
else:# None, 。 stack[-1] ,
peek = stack[-1]
if peek.right and last != peek.right:# , scan。 if last == peek.right
root = root.right
else:# , , , last
if peek == target:
return stack
last = stack.pop()# last 。
root = None# 。 last , stack pop, stack node, stack[-1], else