LCA topic

Description

LCA of two nodes of binary tree

  • Step 1: what is LCA ?

    • 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).
  • Step 2: by applying divide and conquer thought,

    • at each node
    • we are determine if current node is the lca of w and v ?
      • if v and w is not null, and current node is lowest level, current node is lca
      • if we found a v in subtree, w is not found, we determine if current node is w, if it is w, and w is LCA
      • if we found a w in subtree, v is not found, we determine if current node is v, if its v, and v is LCA.
      • if nothing found, //will not happen in this case.
  • Step 3: we utilize bottom-up method, since we need to find lowest level.

    • need to know, whether v or w has been found in left / right subtree.
    • first time
      • fromLeft != null && fromRight != null, lca = root;
      • fromleft == w || fromRight == v, and root == w / v, lca = root;
      //psb candidate lca of w and v at tree
      //how to guarantee this lca is the lowest one?
      public TreeNode LCA(TreeNode root, TreeNode w, TreeNode v) {
          if (root == null) {
              return root;
          } else if (root == w || root == v) {
              return root;
          }
          //root is not w or v
          TreeNode fromLeft = LCA(root.left, w, v);
          TreeNode fromRight = LCA(root.right, w, v);
          //there is only one chance that fromLeft != null && fromRight != null
          if (fromLeft != null && fromRight != null) {
              return root;
          } 
          //this covers the case we already found an LCA.
          return fromLeft == null ? fromRight : fromLeft;
      }
    

    LCA of two nodes of general tree

    • case 1 : 

      among all children, find two non-null return, return root;

    • case 2 :

      among all children, find 1 non-null, return that node.

    • case 3: left == right == null, return null

LCA of Binary Search Tree

     //trick : 先排序w v (w < v)
     public TreeNode LCA(TreeNode root, TreeNode w, TreeNode v) {
         if (root == null) {
             return null;
         }
         if (root == w || root == v) {
             return root;
         }
         TreeNode l = null , r = null;
         if (v.val < root.val) {
             l = LCA(root.left, w, v);
         } else if (w.val > root.val) {
             l = LCA(root.right,w, v);
         } else {
             l = LCA(root.left, w, v);
             r = LCA(root.right,w, v);
         }
         if (l != null && r != null) {
             return root;
         } 
         return l == null ? r : l;
     }

Two nodes distance (LCA variant).

return value: <# found, distance>

  • case 1
    • root == n1 || root == n2 -> return [1,0]
  • case 2
    • left[1,h1] + right[1,h2] -> return [2,h1 + h2];
  • case 3
    • left [0,h1] + right[1,h2] -> return [1,h2 + 1];
  • case 4
    • left[1,h1] + right[0,h2] -> return [1,h1 + 1];
  • case 5
    • left[0,h1] + right[0,h2] -> return [0,0]

Given a binary tree and two nodes, print out path.

    //this is not a good way to use bottom-up, just to demonstrate the idea of using return value
    public List<Integer> findPath(TreeNode root, TreeNode a, TreeNode b) {
        if (root == null) {
          return root;
        }
        if (root == a || root == b) {
          return new ArrayList<Integer>(Arrays.asList(root.val));
        }
        List<Integer> lRes = findPath(root.left,a,b);
        List<Integer> rRes = findPath(root.right,a,b);
        List<Integer> res = new ArrayList<Integer>();
        if (lRes != null && rRes != null) {
            res.addAll(lRes);
            res.add(root.val);
            res.addAll(rRes);
            return res;
        } else if (lRes != null) {
            lRes.add(root.val);
        } else if (rRes != null) {
            rRes.add(root.val);
        }
        return lRes == null ? rRes : lRes;
    }

A better idea is :

  • find root to A path, root to B path.
  • merge two linkedlist until met a common node.

    find deepest LCA of all leaf nodes.

  • Step 1: clarify

    a) Definition of LCA : a node which has >= 2 leaf descendants b) Deepest : height minimum.

              7 
         /    |      \
        4     6       10
       / \            / \
      1   5          9  13
         / \        /     \ 
        3   6      8      18
       /   / \
      2   12 11

results matching ""

    No results matching ""