バイナリツリー共通の祖先(最下位共通祖先の - 二分木)

タイトル

バイナリツリーを考えると、ツリーの指定された2つのノードの最も近い共通の祖先を見つけます。

定義されるような共通の祖先最近Baiduの百科事典:「ツリーT pのルートの2つのノードQについては、xが可能であり、xと同じ大きさP、Q祖先深さであり、共通の祖先ノードXとして表されます(ノードは、それ自身の祖先であることができます)。 "

ルート= [3,5,1,6,2,0,8、NULL、NULL、7,4]を次のように、例えば、二分木所与

IMG

例1:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。

例2:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

説明:

所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉树中。

コードやアイデア

package lowest_common_ancestor_of_a_binary_tree;

import java.util.ArrayList;
import java.util.List;

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
	
	/**
	 * 1.求出较短路径的长房n.
	 * 2.同时遍历p节点的路径与q节点的路径,遍历n个节点,最后一个发现的相同节点,即最近公共祖先.
	 */
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
		List<TreeNode> path = new ArrayList<TreeNode>();//声明遍历用的临时栈
		List<TreeNode> node_p_path = new ArrayList<TreeNode>();//存储p节点路径
		List<TreeNode> node_q_path = new ArrayList<TreeNode>();//存储q节点路径
		int finish = 0;//记录是否完成搜索的变量finish
		preorder(root, p, path, node_p_path, finish);
		
		path = new ArrayList<TreeNode>();
		finish = 0;
		
		preorder(root, q, path, node_q_path, finish);
		int path_len = 0;//较短路径的长度
		if(node_p_path.size()<node_q_path.size()) {
			path_len = node_p_path.size();
		}else {
			path_len = node_q_path.size();
		}
		TreeNode result = new TreeNode(0);
		for (int i = 0; i < path_len; i++) {//同时遍历根到p,q两个节点的路径上的节点
			if(node_p_path.get(i)==node_q_path.get(i)) {
				result = node_p_path.get(i);
			}
		}
		return result;
    }
    
    //求至某节点路径
    private void preorder(TreeNode node,//正在遍历的节点 
			TreeNode search, //待搜索节点
			List<TreeNode> path, //遍历时的节点路径栈
			List<TreeNode> result, //最终搜索到节点search的路径结果
			int finish) {//记录是否找到节点search的变量,未找到时是0,找到为1
		if (node == null || finish == 1) {//当node为空或已找到search节点直接返回,结束搜索
			return;
		}
		path.add(node);//先序遍历,将节点压入path栈
		if (node.val == search.val) {//当找到search节点后,标记finish变量
			finish = 1;
			result.addAll(path);//将当前的path存储到result中
		}
		preorder(node.left, search, path, result, finish);//深度遍历node左孩子
		preorder(node.right, search, path, result, finish);//深度遍历node右孩子
		path.remove(path.size() - 1);//结束遍历node时,将node节点弹出path栈
	}
    
    public static void main(String[] args) {
    	TreeNode a = new TreeNode(3);
    	TreeNode b = new TreeNode(5);
    	TreeNode c = new TreeNode(1);
    	TreeNode d = new TreeNode(6);
    	TreeNode e = new TreeNode(2);
    	TreeNode f = new TreeNode(0);
    	TreeNode x = new TreeNode(8);
    	TreeNode y = new TreeNode(7);
    	TreeNode z = new TreeNode(4);
    	a.left = b;
    	a.right = c;
    	b.left = d;
    	b.right = e;
    	c.left = f;
    	c.right = x;
    	e.left = y;
    	e.right = z;
    	
    	Solution solve = new Solution();
    	TreeNode result = solve.lowestCommonAncestor(a, b, f);
    	System.out.printf("lowestCommonAncestor = %d\n", result.val);
    	result = solve.lowestCommonAncestor(a, d, z);
    	System.out.printf("lowestCommonAncestor = %d\n", result.val);
    	result = solve.lowestCommonAncestor(a, b, y);
    	System.out.printf("lowestCommonAncestor = %d\n", result.val);
	}
    
}

実行時:13ミリ秒は、ユーザーの38.93パーセントのすべてのJavaの提出を打つ
メモリ消費量:36.3メガバイト、Javaの提出内のすべてのユーザーの75.34パーセントを破りました

予約限定トラバーサル、順トラバーサルで、後順トラバーサル

前順走査は、順トラバーサル、後順に、二回横断し、かつてない言及します。それは私深さ優先探索、時間の前文には、左の部分木、右のサブツリーにアクセスしていないとき、私は、このノードをやって見たことを意味します。あなたはその左部分木行わ何かを訪問した後、このシーケンスは、表されます。後続のは、ノードにフォールバックする、見返りに、そうしてきた、表現し、我々は、これは、シーケンスの後に呼び出されます。

公開された151元の記事 ウォン称賛47 ビュー23万+

おすすめ

転載: blog.csdn.net/e891377/article/details/103598236