算法:二叉树公共父节点
题目
https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/
思路1
采用从上到下找当节点是不是p的父节点,然后反向遍历p的父节点,返回是不是q的父节点就行。
代码1
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
/** 解法1:找出p所有的父节点,然后找出q所有的父节点。反向遍历能找到公共的子节点 */
if (isParent(p , q) ) {
return p;
}
if (isParent(q, p)) {
return q;
}
List<TreeNode> parents = new ArrayList<TreeNode>();
addParent(root, p,parents);
for(int i = parents.size() -1 ; i >=0 ;i --) {
TreeNode current = parents.get(i);
if (isParent(current, q)) {
return current;
}
}
for (int i = 0; i < parents.size();i ++) {
System.out.println(parents.get(i).val);
}
return root;
}
private void addParent(TreeNode root, TreeNode target, List<TreeNode> parents) {
if (isParent(root, target)) {
parents.add(root);
}
if (root == null) {
return;
}
addParent(root.left, target, parents);
addParent(root.right, target, parents);
}
private boolean isParent(TreeNode parent, TreeNode child) {
if (parent == null) {
return false;
}
if (parent == child) {
return true;
}
return isParent(parent.left,child) || isParent(parent.right, child);
}
}
思路2
如果有个节点是p,q的公共父节点节点,那么这个节点的子树一定包含分别包含p,q,或者说这个节点就是p,他左右子树里面包含q,或者这个节点是q他的子树包含p。
代码2
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private TreeNode ans;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
dfs(root, p, q);
return ans;
}
private boolean dfs(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return false;
}
boolean lson = dfs(root.left, p, q); //是pq是否有个在左子树里面
boolean rson = dfs(root.right, p, q); //pq是否有个在右子树里面
if (lson && rson || (root.val == p.val || root.val == q.val) && (lson || rson)) {
ans = root;
}
return lson || rson || (root.val == p.val || root.val == q.val); // 如果满足都在左或者都在右就是root是pq的公共子节点,不满足 lson || rson 要考虑一种特殊的情况,就是p是q的父节点。即p为Root
}
}
题目: 二叉搜索树的公共父节点。
二叉搜索树的性质,中序遍历的结果是从大到小的,也就是左子树的节点值始终比根节点小,右子树的值始终是比根节点的大。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}
if (root.val < q.val && root.val < p.val) {
return lowestCommonAncestor(root.right, p, q );
} else if (root.val> q.val && root.val > p.val) {
return lowestCommonAncestor(root.left, p, q );
}
return root;
}
}