動機
我忘了localty
Problem
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p
and q
as the lowest node in T
that has both p
and q
as descendants (where we allow a node to be a descendant of itself).”
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1Output: 3Explanation: The LCA of nodes 5 and 1 is 3.
Example 2:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4Output: 5Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
Example 3:
Input: root = [1,2], p = 1, q = 2Output: 1
Constraints:
- The number of nodes in the tree is in the range
[2, 105]
. -109 <= Node.val <= 109
- All
Node.val
are unique. p != q
p
andq
will exist in the tree.
Sol
原本是用bfs,放node與到root的path,之後做intersection
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
pchain, qchain = None, None
qu = deque([[root,[root]]]) # root, path to root
while not pchain or not qchain:
r, path = qu.popleft()
pchain = path if not pchain and p is r else pchain
qchain = path if not qchain and q is r else qchain
for x in [x for x in [r.left,r.right] if x]:
qu.append([x,path[::]+[x]])
if len(pchain) != len(qchain):
a,b = min([pchain,qchain], key=lambda x: len(x)), max([pchain,qchain], key=lambda x: len(x))
while len(b) > len(a):
if b[-1] is a[-1]:
return b[-1]
else:
b.pop()
else:
a,b = pchain,qchain
while a[-1] is not b[-1]:
a.pop()
b.pop()
return a[-1]
但是如果用dfs可以一次檢查兩個ptr,但是要用global去存第一個祖先
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root:
return None
lca = None
def dfs(r):
nonlocal lca
if not r:
return False, False
else:
isp,isq = (r is p), (r is q)
if not isp or not isq:
a,b = dfs(r.left)
x,y = dfs(r.right)
isp, isq = (isp or a or x), (isq or b or y)
if not lca and isp and isq:
lca = r
return isp,isq
dfs(root)
return lca
這題保證p,q一定在tree中,這樣就只要dfs到p,q,之後只要回程檢查有沒有一個root是同時看到p,q的就是LCA 沒有看到就會是null
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (!root || root == p || root == q)
return root;
else {
auto l = lowestCommonAncestor(root->left, p, q), r = lowestCommonAncestor(root->right, p, q);
if (l && r) // 這裡就是LCA
return root;
else if (l) // 一定在其中一邊
return l;
else
return r;
}
}
};