[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/feixiangcode/algorithm/master/Week_02/id_26/Leetcode_236_26.java [Back]  [Original]

package com.fanlu.leetcode.binarytree;
// Source : https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/
// Id     : 236
// Author : Fanlu Hai
// Date   : 2018-04-24
// Other  : lowest common ancestor (LCA): 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).
// Tips   :

import java.util.LinkedList;
import java.util.Queue;

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 * int val;
 * TreeNode left;
 * TreeNode right;
 * TreeNode(int x) { val = x; }
 * }
 */

public class LowestCommonAncestorOfABinaryTree {

    private TreeNode ans;

    // This answer is copied from leetcode submission analysis sample
    // 100.00% (20% faster than original)  44.21%
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {

        this.recurse(root, p, q);
        return this.ans;
    }

    private boolean recurse(TreeNode node, TreeNode p, TreeNode q) {

        if (node == null) {
            return false;
        }

        // rec left
        // it's very hard for me to write below code even though it's nothing hard.
        int left = this.recurse(node.left, p, q) ? 1 : 0;
        int right = this.recurse(node.right, p, q) ? 1 : 0;

        int mid = (node == p) || (node == q) ? 1 : 0;

        // this is better than comparing objects
        if (mid + left + right >= 2) {
            this.ans = node;
        }
        return (mid + left + right > 0);

    }


    //65.83%  40.60%
    // this is fast enough to my understanding, but there are more elegant and faster ways to do the same steps
    public TreeNode lowestCommonAncestorOriginal(TreeNode root, TreeNode p, TreeNode q) {

        if (null == root || root == p || root == q)
            return root;
        TreeNode left = lowestCommonAncestorOriginal(root.left, p, q);
        TreeNode right = lowestCommonAncestorOriginal(root.right, p, q);

        if (null != left && null != right) {
            return root;
        } else if (null == right) {
            return left;
        } else {
            // null == left
            return right;
        }
        //return left == null ? right : right == null ? left : root;
    }

    /**
     * below are some no very successfull attampts
     */
    Queue pNodeList = new LinkedList();
    Queue qNodeList = new LinkedList();

    //! Time Limit Exceeded
    public TreeNode lowestCommonAncestorTooSlow(TreeNode root, TreeNode p, TreeNode q) {
        TreeNode result = root;
        dfsNode(root, p, q, new LinkedList());
        while (!pNodeList.isEmpty()) {
            TreeNode tmp = pNodeList.poll();
//            System.out.println(tmp);
            if (tmp != qNodeList.poll()) {
                break;
            }
            result = tmp;
        }
        return result;
    }

    public void dfsNode(TreeNode treeNode, TreeNode p, TreeNode q, Queue queue) {
        if (null == treeNode)
            return;

        Queue tmpQueue = new LinkedList();
        tmpQueue.addAll(queue);

        tmpQueue.add(treeNode);
        if (treeNode.val == p.val) {
            pNodeList = tmpQueue;
        }

        if (treeNode.val == q.val) {
            qNodeList = tmpQueue;
        }

        dfsNode(treeNode.left, p, q, tmpQueue);
        dfsNode(treeNode.right, p, q, tmpQueue);
    }


    Queue pList = new LinkedList();
    Queue qList = new LinkedList();


    // implemented the int version
    public int lowestCommonAncestorReturnInt(TreeNode root, TreeNode p, TreeNode q) {
        int result = root.val;
        dfsValue(root, p.val, q.val, new LinkedList());
        while (!pList.isEmpty()) {
            int tmp = pList.poll();
//            System.out.println(tmp);
            if (tmp != qList.poll()) {
                break;
            }
            result = tmp;
        }
        return result;
    }

    public void dfsValue(TreeNode treeNode, int p, int q, Queue queue) {
        if (null == treeNode)
            return;

        Queue tmpQueue = new LinkedList();
        tmpQueue.addAll(queue);

        tmpQueue.add(treeNode.val);
        if (treeNode.val == p) {
            pList = tmpQueue;
        }

        if (treeNode.val == q) {
            qList = tmpQueue;
        }

        dfsValue(treeNode.left, p, q, tmpQueue);
        dfsValue(treeNode.right, p, q, tmpQueue);
    }

    public static void main(String[] args) {
        TreeNode treeNode1 = new TreeNode(1);
        TreeNode treeNode2 = new TreeNode(2);
        TreeNode treeNode3 = new TreeNode(3);
        TreeNode treeNode4 = new TreeNode(4);
        TreeNode treeNode5 = new TreeNode(5);
        TreeNode treeNode6 = new TreeNode(6);
        TreeNode treeNode7 = new TreeNode(7);

        treeNode1.left = treeNode2;
        treeNode2.left = treeNode4;
        treeNode2.right = treeNode5;
        treeNode5.right = treeNode3;
        treeNode3.left = treeNode6;
        treeNode3.right = treeNode7;

        LowestCommonAncestorOfABinaryTree lowestCommonAncestorOfABinaryTree = new LowestCommonAncestorOfABinaryTree();
        lowestCommonAncestorOfABinaryTree.dfsValue(treeNode1, 7, 6, new LinkedList());

        for (int i : lowestCommonAncestorOfABinaryTree.pList) {
            System.out.print(i + "*");
        }
        System.out.println();
        for (int i : lowestCommonAncestorOfABinaryTree.qList) {
            System.out.print(i + "-");
        }
        System.out.println();

        System.out.println("result: " + lowestCommonAncestorOfABinaryTree.lowestCommonAncestorReturnInt(treeNode1, treeNode7, treeNode6));
    }

}

Web Proxy Viewer  |  New URL  |  Original Page