lowest node's LCA

給一個 二叉樹/多叉樹 , 求最深節點的最小公共父節點。

這題算是對LCA的一個擴展,由給定兩個點換成了最深兩個點,由二叉樹換成多樹。

難點1. 我們要返回什麼?

不難看出來, 最後要返回一個node,所以TreeNode 肯定是需要返回的變量之一;另外一個是最長路徑或者說最大深度。所以說,每個node往上層返的時候都需要返回這2個變量,一個是當前以node爲root的時候最深common節點,一個是深度deep。爲什麼說這是難點之一?大部分leetcode的樹的題,基本上都是隻需要返回一個變量的,這時候要返回兩個變量。於是需要創建一個class,這個類裏面包含一個node跟一個int類型的MAXdeep變量。 所以說當對任意一個節點調用這個函數的時候,都將返回,commonAncestorOfDeepest的節點,以及這個節點所在路徑的depth。

難點2. 多叉樹,而不是二叉樹。

或許你覺得多叉數,本質上與二叉樹沒有區別,不就是多了幾個下一級的指針嘛?二叉樹只有left, right。 多叉樹則有N個,僅此而已。可是就因爲需要用一個list來保存多叉樹的指針,又會影響遞歸函數內的判斷邏輯的複雜程度。說的更加直白一點,二叉樹,你只需要比較一下left跟right就好了,而多叉樹你需要寫loop,以及count來遍歷,所有的指針。


private static class Solution {-google 1point3acres
        private class ReturnVal {
            public int depth;   //The depth of the deepest leaves on the current subtree
            public TreeNode lca;//The lca of the deepest leaves on the current subtree

            public ReturnVal(int d, TreeNode n) {
                depth = d;
                lca = n;
            }
        }

        public TreeNode LowestCommonAncestorOfDeepestLeaves(TreeNode root) {
            ReturnVal res = find(root, 0);
            return res.lca;
        }

        private ReturnVal find(TreeNode root, int depth) {
            if(root == null) {
                return new ReturnVal(-1, null);
            } else {
                ReturnVal lRes = find(root.left, depth+1);
                ReturnVal rRes = find(root.right, depth+1);

                if(lRes.depth == rRes.depth) {
                    return new ReturnVal(lRes.depth==-1?depth:lRes.depth, root);
                } else {
                    return new ReturnVal(Math.max(rRes.depth, lRes.depth), rRes.depth>lRes.depth?rRes.lca:lRes.lca);
                }
            }
        }
    }

class TreeNode{
        int val;
        ArrayList<TreeNode> children;
        public TreeNode(int val){
                this.val = val;
                children = new ArrayList<>();
        }
}
 
class Result{
        TreeNode node;
        int maxDepth;
        public Result(TreeNode node, int maxDepth){
                this.node = node;
                this.maxDepth = maxDepth;
        }
}
 
public class LowestCommonAncestorForAnyTree{
 
        public static TreeNode find(TreeNode root){
        if(root == null || root.children.isEmpty()) return root;
                return helper(root).node;
        }
 
        public static Result helper(TreeNode root){
                if(root.children.isEmpty()) return new Result(root, 1);
                
                int size = root.children.size();
                int maxDepth = Integer.MIN_VALUE;
 
                Result r = new Result(root, maxDepth);
 
                for(int i = 0; i < size; i++){
                        Result tmp = helper(root.children.get(i));
                        if(tmp.maxDepth > maxDepth){
                                maxDepth = tmp.maxDepth;
                                r.node = tmp.node;
                                r.maxDepth = tmp.maxDepth + 1;
                        }
 
                        //Find multiple nodes which all are deepest leaf nodes 
                        else if(tmp.maxDepth == maxDepth){
                                r.node = root;
                        }        
                }
 
                return r;
        }
        public static void main(String[] args){
                TreeNode n1 = new TreeNode(1);
                TreeNode n2 = new TreeNode(2);.
                TreeNode n3 = new TreeNode(3);
                TreeNode n4 = new TreeNode(4);
                TreeNode n5 = new TreeNode(5);
                TreeNode n6 = new TreeNode(6);
                TreeNode n7 = new TreeNode(7);
                TreeNode n8 = new TreeNode(8);
                TreeNode n9 = new TreeNode(9);
                TreeNode n10 = new TreeNode(10);
                n1.children.add(n2); 
                n1.children.add(n3);
                n1.children.add(n4);
                n2.children.add(n5);
                n2.children.add(n6);
                n4.children.add(n7);
                n5.children.add(n8);
                n5.children.add(n9);
                n6.children.add(n10);
                TreeNode res = find(n1);
                System.out.println(res.val);
 
        }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章