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).”
Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]
_______3______
/
___5__ ___1__
/ /
6 _2 0 8
/
7 4
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of 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 = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself
according to the LCA definition.
Note:
* All of the nodes' values will be unique.
* p and q are different and both values will exist in the binary tree.
postOrder分治法。
1.返回TreeNode,逻辑抽象。是P传P(root),是Q传Q(root),左右都有东西传说明这个是lca传(root),左右只有一个有东西说明这个是更高级的ca传有东西的那个结果,左右都没东西说明这个什么都不是传null(左右随便选一个传)
2.返回类型较复杂,逻辑清楚。hasP, hasQ, lca。逻辑是hasP hasQ根据左右还有自己的状态来得到,lca是在本层hasP&&hasQ的时候更新,下面有就帮忙传上去,下面没有就传自己。
法1:
class Solution { public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if (root == null) { return null; } TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); if (root == p || root == q) { boolean rootright = true; return root; } if (left != null && right != null) { boolean notempty = true; return root; } return right == null ? left : right; } }
法2:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { private class ResultType{ boolean hasP; boolean hasQ; TreeNode lca; public ResultType(boolean hasP, boolean hasQ, TreeNode lca) { this.hasP = hasP; this.hasQ = hasQ; this.lca = lca; } } public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { ResultType rt = helper(root, p, q); return rt.lca; } private ResultType helper(TreeNode root, TreeNode p, TreeNode q) { if (root == null) { return new ResultType(false, false, null); } // if (root == p) { // return new ResultType(true, false, null); // } // if (root == q) { // return new ResultType(false, true, null); // } // P1: 一个是不要处理的这么细,拿root和pq是否相等也这样处理,尽可能包含在下面的递归里。另一个是hasP本来就要考虑当前root是不是的情况,如果左右都没有p但本root就是p那也得是hasP啊。这样才能正确处理到p是q的祖先的情况。 ResultType left = helper(root.left, p, q); ResultType right = helper(root.right, p, q); boolean hasP = left.hasP || right.hasP || root == p; boolean hasQ = left.hasQ || right.hasQ || root == q; TreeNode lca = null; if (hasP && hasQ) { if (left.lca != null) { lca = left.lca; } else if (right.lca != null) { lca = right.lca; } else { lca = root; } } return new ResultType(hasP, hasQ, lca); } }