关于LeetCode中Lowest Common Ancestor of a Binary Search Tree一题的理解

来源:互联网 发布:淘宝直通车开车后流程 编辑:程序博客网 时间:2024/06/03 16:19

题目如下:

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

        _______6______       /              \    ___2__          ___8__   /      \        /      \   0      _4       7       9         /  \         3   5

For example, the lowest common ancestor (LCA) of nodes2 and8 is 6. Another example is LCA of nodes2 and4 is 2, since a node can be a descendant of itself according to the LCA definition.

    怎么说呢?这道题算是到目前为止Easy难度我做出来的题中,耗时最多的一次,至于原因还是因为我菜(笑)。总之,题干的意思也算比较明确了,给定一个二叉搜索树,给定两个节点,要求程序返回这两个节点的最近祖先节点,如果还是不明白可以看一下上面的链接,里面是维基百科中关于LCA(lowest common ancestor)的详细解释。好吧,我果然又又又又又看错题了,根本没注意到是个二叉搜索树,我还以为是普通的树,我当时还奇怪万一出现两个相同val值的目标的节点咋办?我的想法是还是使用递归的思路,判断节点的val值及节点左儿子、右儿子节点的值。根据值的不同,返回不同的结果。我在类中还设置了一个静态变量,如果满足条件即找到了这样两个节点就将其置为true,当然了它的初始值肯定是false了。这个静态变量的加入也是为了在已经找到目标节点但递归却没有结束的时候,一直向上返回目标节点。这样就算它的兄弟节点是null等其他类型,也不会影响最终的结果。光听我这么说肯定是云里雾里的,还是直接上代码比较实惠,已Accepted的代码如下:
public class Solution {    static boolean isFind=false;    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {        if(root == null){            return null;        }        root.left = lowestCommonAncestor(root.left, p, q);        root.right = lowestCommonAncestor(root.right, p ,q);        if(((root.val == p.val || root.val == q.val) && root.right!=null && (root.right.val == p.val || root.right.val == q.val)) ||         ((root.val == p.val || root.val == q.val) && root.left!=null && (root.left.val == p.val || root.left.val == q.val)) ||         (root.left!=null && root.right!=null &&(root.right.val == p.val || root.right.val == q.val) && (root.left.val == p.val || root.left.val == q.val))){            isFind = true;            return root;        }else if(root.right!=null && (root.right.val == p.val || root.right.val == q.val)){            return root.right;        }else if(root.left!=null && (root.left.val == p.val || root.left.val == q.val)){            return root.left;        }else if(root.val == p.val || root.val == q.val){            return root;        }else if(isFind){            return root.left==null?root.right:root.left;        }else{            return null;        }    }}
     感觉还是超吓人的,我感觉主要原因还是没有利用上“二叉搜索树”这个条件,那我们还是来看看评论区的大神们都是如何实现的吧!来来来客官,X大的来了,这个解决方案啊,看得我都excited了!快快快,直接上代码:

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {        for(; ;) {        if((p.val - root.val) * (q.val - root.val) <= 0)return root;        if(p.val < root.val)    root = root.left;        else root = root.right;        }    }
    最关键的代码就是第二行的代码,如果给定节点p和q的val值一个比当前节点大(或等于),另一个比当前节点小(或等于),说明当前节点肯定是需要返回的目标节点,仔细想一想真的是这样!比我的代码不知道高到哪里去了!还有一种是它的递归形式,如下所示:

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {        if(root.val > p.val && root.val > q.val){            return lowestCommonAncestor(root.left, p, q);        }else if(root.val < p.val && root.val < q.val){            return lowestCommonAncestor(root.right, p, q);        }else{            return root;        }    }
    如果你还想更简单点,下面这个只有三行,思路一样:

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {    while ((root.val - p.val) * (root.val - q.val) > 0)        root = p.val < root.val ? root.left : root.right;    return root;}
    大致就是这样了,我记得昨天我还说过要好好看题,今天直接实力打脸,没事我的脸一点都不疼,就是肿了......果然套路和岳老师说的一样,"我说的字啊,每一个都有用!"。

0 0
原创粉丝点击