zoukankan      html  css  js  c++  java
  • leetcode 236 二叉树的最近公共祖先

    给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

    百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

    例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4]

     Java solution1 

      static  int BOTH_PENDING = 2;
        static  int LEFT_DONE = 1;
        static  int BOTH_DOWN = 0;
        public TreeNode lowestCommonAncestor1(TreeNode root, TreeNode p, TreeNode q) {
            Stack<Pair<TreeNode , Integer >>   stack = new Stack<>();
            stack.push(new Pair<TreeNode, Integer>(root, BOTH_PENDING));
    
            boolean one_node_found = false;
            TreeNode LCA = null;
            while(!stack.empty()){
                Pair<TreeNode, Integer> pair = stack.peek();
                TreeNode parentNode = pair.getKey();
                int      parentState = pair.getValue();
                if( parentState != BOTH_DOWN){
                    TreeNode childNode ;
                    if( parentState == BOTH_PENDING){
                        if( parentNode == p || parentNode == q){
                             if(one_node_found){
                                   return LCA;
                             }
                             else{
                                one_node_found = true;
                                LCA = stack.peek().getKey();
                             }
                        }
                        childNode = parentNode.left;
                    }
                    else{
                        childNode = parentNode.right;
                    }
                    stack.pop();
                    stack.push(new Pair<TreeNode, Integer>(parentNode, parentState -1 ));
                    if(childNode != null){
                        stack.push(new Pair<TreeNode, Integer>(childNode, BOTH_PENDING));
                    }
                }
                else{
                   if(LCA == stack.pop().getKey() && one_node_found){
                       LCA = stack.peek().getKey();
                   }
                }
            }
            return LCA;
        }

    Java Solution2 

     public TreeNode lowestCommonAncestor2(TreeNode root, TreeNode p, TreeNode q) {
            if(root == null){
                return root;
            }
            if(root == p || root == q){
                return root;
            }
            TreeNode  left = lowestCommonAncestor2(root.left , p,q);
            TreeNode  right = lowestCommonAncestor2(root.right, p, q);
            if(left !=null && right !=null){
                return root;
            }
            else if(left !=null){
                return left;
            }
            else if(right != null){
                return right;
            }
            return null;
        }
    # Definition for a binary tree node.
    class TreeNode:
        def __init__(self, x):
            self.val = x
            self.left = None
            self.right = None
    # my solution
    # class Solution:
    #     def dfs(self, root: 'TreeNode', p: 'TreeNode' , stack: list) :
    #         if( root == None):
    #             return None
    #         if(root == p ):
    #             stack.append(root)
    #             return True
    #         ans = False
    #         if( root.left != None):
    #             stack.append(root)
    #             ans = self.dfs(root.left,p,  stack)
    #             if(not ans):
    #                  stack.pop(-1)
    #             else:
    #                 return ans
    #         if ( root.right != None):
    #             stack.append(root)
    #             ans = self.dfs(root.right,p,  stack)
    #             if(not ans):
    #                  stack.pop(-1)
    #             else:
    #                 return ans
    #
    #         return ans
    #
    #     def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
    #         p_stack = []
    #         self.dfs(root, p,p_stack)
    #         q_stack = []
    #         self.dfs(root, q,q_stack)
    #
    #         p_stack.reverse()
    #         q_stack.reverse()
    #         for i_node in p_stack:
    #             for j_node in q_stack:
    #                 if( i_node.val == j_node.val ):
    #                     return i_node
    
    # 方法一:递归
    # class Solution:
    #     def __init__(self):
    #         self.ans = None
    #
    #     def lowestCommonAncestor(self, root, p, q):
    #         def recurse_tree(current_node):
    #             if not current_node:
    #                 return False
    #             left = recurse_tree( current_node.left)
    #             right = recurse_tree( current_node.right)
    #             mid = current_node == p or current_node == q
    #             if( mid + left + right >= 2):
    #                 self.ans = current_node
    #             return mid or left or right
    #         recurse_tree(root)
    #         return self.ans
    
    def pre_order_receverse(root : 'TreeNode'):
        stack = []
        pNode = root
        while( pNode != None or len(stack) > 0 ):
            if( pNode != None ):
                print(pNode.val)
    
                pNode =  pNode.left
            else:
                node = stack.pop()
                stack.append(pNode)
                pNode = node.right
    
    def dfs_order_receverse(root : 'TreeNode'):
        stack = [root]
        # pNode = root
        while( len(stack) > 0 ):
            pNode = stack.pop(-1)
            print(pNode.val)
            if( pNode.right != None  ):
                stack.append(pNode.right)
            if( pNode.left != None  ):
                stack.append(pNode.left)
    
    # 方法二:使用父指针迭代
    # class Solution:
    #     def lowestCommonAncestor(self, root, p, q):
    #         stack = []
    #         parent = {}
    #         parent[root] = None
    #         stack.append(root)
    #         while p not in parent or q not in parent:
    #             node = stack.pop(-1)
    #             if(node.left ):
    #                 parent[node.left] = node
    #                 stack.append(node.left)
    #             if(node.right):
    #                 parent[node.right] = node
    #                 stack.append(node.right)
    #         ancestor = set()
    #         while(p):
    #             ancestor.add(p);
    #             p = parent[p]
    #         while( q not in ancestor):
    #             q =  parent[q]
    #         return  q
    
    # 方法三 无父指针的迭代
    class Solution:
    
        # Three static flags to keep track of post-order traversal.
    
        # Both left and right traversal pending for a node.
        # Indicates the nodes children are yet to be traversed.
        BOTH_PENDING = 2
        # Left traversal done.
        LEFT_DONE = 1
        # Both left and right traversal done for a node.
        # Indicates the node can be popped off the stack.
        BOTH_DONE = 0
    
        def lowestCommonAncestor(self, root, p, q):
    
            stack = [(root, Solution.BOTH_PENDING)]
            one_node_found = False
            LCA_index = -1
            while stack:
                parent_node, parent_state = stack[-1]
                if parent_state != Solution.BOTH_DONE:
                    if parent_state == Solution.BOTH_PENDING:
                        if parent_node == p or parent_node == q:
                            if one_node_found:
                                return stack[LCA_index][0]
                            else:
                                one_node_found = True
                                LCA_index = len(stack) - 1
                        child_node = parent_node.left
                    else:
                        child_node = parent_node.right
                    stack.pop()
                    stack.append((parent_node, parent_state - 1))
                    if child_node:
                        stack.append((child_node, Solution.BOTH_PENDING))
                else:
                    if one_node_found and LCA_index == len(stack) - 1:
                        LCA_index -= 1
                    stack.pop()
    
            return None
    
    
    if __name__ == '__main__':
        root = TreeNode(3)
        node1 = TreeNode(5)
        node2 = TreeNode(1)
        node3 = TreeNode(6)
        node4 = TreeNode(2)
        node5 = TreeNode(0)
        node6 = TreeNode(8)
        node7 = TreeNode(7)
        node8 = TreeNode(4)
    
        root.left = node1
        root.right = node2
        node1.left = node3
        node1.right = node4
        node2.left = node5
        node2.right = node6
        node4.left = node7
        node4.right = node8
    
        p = node1
        q = node2
        # dfs_order_receverse(root)
        print( Solution().lowestCommonAncestor(root, p, q).val )

     Java solution1 

  • 相关阅读:
    创建文件并写入内容
    java自动压缩文件并加密
    Java自动发送带图片邮件(带附件)
    eclipse正则表达式搜索
    解决:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):
    spring整合mybatis(原始dao和mapper代理两种方式)
    (解决)mysql1366中文显示错误的终极解决方案
    pdf合并、拆分工具
    ScheduledExecutorService定时方法
    json数据包含特殊字符解析失败
  • 原文地址:https://www.cnblogs.com/xianbin7/p/11366741.html
Copyright © 2011-2022 走看看