【牛客 – 剑指offer】JZ68 二叉搜索树的最近公共祖先 两种方案(递归、非递归) Java实现

  • Post author:
  • Post category:java





剑指offer题解汇总 Java实现


https://blog.csdn.net/guliguliguliguli/article/details/126089434



本题链接


知识分类篇 – 树 – JZ68 二叉搜索树的最近公共祖先



题目

在这里插入图片描述



思路 & 代码



方案一 非递归

题目所给的二叉树是二叉搜索树,即比根节点的值小的点均在根节点的左边,比根节点的值大的点,均在根节点的右边

  1. 依据这个性质,用arrayList记录下找到两个指定节点的路径

  2. 最后,比较两个arrayList,返回它们的路径中最后一个相同的数,就是它们的最近公共祖先

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param root TreeNode类
     * @param p    int整型
     * @param q    int整型
     * @return int整型
     */
    public int lowestCommonAncestor(TreeNode root, int p, int q) {

        // write code here
        ArrayList<Integer> p1 = findPath(root, p);
        ArrayList<Integer> p2 = findPath(root, q);

        int res = 0;
        for (int i = 0; i < p1.size() && i < p2.size(); i++) {
            int p1_value = p1.get(i);
            int p2_value = p2.get(i);
            if (p1_value == p2_value) {
                res = p1_value;
            } else {
                break;
            }
        }
        return res;

    }


    public ArrayList<Integer> findPath(TreeNode node, int target) {
        ArrayList<Integer> list = new ArrayList<>();
        while (node.val != target) {
            list.add(node.val);
            if (target > node.val) {
                node = node.right;
            } else {
                node = node.left;
            }
        }
        list.add(target);
        return list;
    }
}



方案二 递归


递归思想

递归是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。因为递归过程,最重要的就是查看能不能将原本的问题分解为更小的子问题,这是使用递归的关键。

而二叉树的递归,则是将某个节点的左子树、右子树看成一颗完整的树,那么对于子树的访问或者操作就是对于原树的访问或者操作的子问题,因此可以自我调用函数,不断进入子树。


思路

  1. 判断传入的根节点,是否为空,如果为空,则不存在找两个节点最近公共祖先的问题,返回空即可

  2. 如果两个节点中,其中

    一个结点

    的值

    大于

    根节点的值,

    另一个结点

    的值,

    小于

    根节点的值,那么根节点就是这两个节点的最近公共祖先。

    • 特殊情况,其中

      某一个节点

      的值

      等于

      根节点的值,且题目中明确表示p和q是不同的节点,那么根节点也是这两个节点的公共节点。
  3. 如果两个节点中,两个节点的值

    都小于

    根节点的值,那么调用方法自身,其中的TreeNode类型的参数赋值为root.left,即,两个节点的公共祖先一定在这棵二叉搜索树的左子树上

  4. 如果两个节点中,两个节点的值

    都大于

    根节点的值,那么调用方法自身,其中的TreeNode类型的参数赋值为root.righth,即,两个节点的公共祖先一定在这棵二叉搜索树的右子树上

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param root TreeNode类
     * @param p    int整型
     * @param q    int整型
     * @return int整型
     */
    public int lowestCommonAncestor(TreeNode root, int p, int q) {
        
        if (root==null){
            return -1;
        }
        if ((p >= root.val && q <= root.val) || (p <= root.val && q >= root.val)) {
            return root.val;
        }
        if (p < root.val && q < root.val) {
            return lowestCommonAncestor(root.left, p, q);
        }
        //if (p > root.val && q > root.val) {
        return lowestCommonAncestor(root.right, p, q);

    }
}



版权声明:本文为guliguliguliguli原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。