NC102 在二叉树中找到两个节点的最近公共祖先
注:本题保证二叉树中每个节点的val值均不相同。
如当输入[3,5,1,6,2,0,8,#,#,7,4],5,1时,二叉树{3,5,1,6,2,0,8,#,#,7,4}如下图所示:
所以节点值为5和节点值为1的节点的最近公共祖先节点的节点值为3,所以对应的输出为3。 示例1 输入:
[3,5,1,6,2,0,8,#,#,7,4],5,1
返回值: 3
分析思路:
思路1:
通过遍历,找到o1,o2节点,然后回溯找到祖先阶段。
为了完成这个目标,需要反向遍历整颗树。
但是,树形结构,没有反向指针。所以,先遍历整个树,构建反向指针。
需要存储反向指针数据,而且需要预先遍历。
所以相对也比较耗时。
例如输入为:
{27,32,34,19,41,17,18,9,14,44,39,#,#,24,30,#,#,#,2,7,42,28,36,#,#,11,6,#,1,#,#,#,31,16,4,22,33,#,#,#,5,10,15,37,12,8,#,35,3,#,23,21,#,#,#,29,#,#,#,40,#,#,#,#,#,#,#,#,#,13,43,#,#,#,#,#,#,25,20,#,#,38,#,26},32,38
找元素32,38 节点的最近祖先。
二叉树:
{27,32,34,19,41,17,18,9,14,44,39,#,#,24,30,#,#,#,2,7,42,28,36,#,#,11,6,#,1,#,#,#,31,16,4,22,33,#,#,#,5,10,15,37,12,8,#,35,3,#,23,21,#,#,#,29,#,#,#,40,#,#,#,#,#,#,#,#,#,13,43,#,#,#,#,#,#,25,20,#,#,38,#,26}
主要代码:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
Map<Integer, Integer> map = new HashMap();
public void dfs(TreeNode root) {
if (root.left != null) {
map.put(root.left.val, root.val);
dfs(root.left);
}
if (root.right != null) {
map.put(root.right.val, root.val);
dfs(root.right);
}
}
/**
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
public int lowestCommonAncestor(TreeNode root, int o1, int o2) {
// write code here
// 遍历反向指针
dfs(root);
// o1节点的所有父节点,含o1节点本身
Set<Integer> o1Parent = new HashSet();
o1Parent.add(o1);
int tmp = o1;
for (; ; ) {
Integer rootV = map.get(tmp);
if (rootV == null) {
break;
}
o1Parent.add(rootV);
if (rootV == root.val) {
break;
}
tmp = rootV;
}
// o2节点向祖先节点回溯,找到最近的祖先节点
Integer o2Root = o2;
while (o2Root != null) {
if (o1Parent.contains(o2Root)) {
return o2Root;
}
if (o2Root == root.val) {
return root.val;
}
o2Root = map.get(o2Root);
}
return root.val;
}
}
思路2:
使用递归的,解决方案,将问题分解。
1.如果root 节点 和o1, o2 相等,那么返回节点root。
2.如果root节点 和 o1, o2 都不相等,子任务分解:
情况1:
如果一个节点在左子树。
另外一个节点在右子树。
那么当前子任务的根节点就是最近的祖先节点
情况2:
如果节点不在左子树,说明两个节点都在右子树。那么放弃搜索左子树,子问题搜索右子树。
情况3:
如果节点不在右子树,说明两个节点都在左子树。那么放弃搜索右子树,子问题搜索左子树。
代码:
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
public int lowestCommonAncestor(TreeNode root, int o1, int o2) {
// write code here
if( root == null){
return -1;
}
if(root.val == o1 || root.val == o2){
return root.val;
}
//
int left = lowestCommonAncestor(root.left, o1, o2);
int right = lowestCommonAncestor(root.right, o1, o2);
if(left == -1){
return lowestCommonAncestor(root.right, o1, o2);
}
if(right == -1){
return lowestCommonAncestor(root.left, o1, o2);
}
return root.val;
}
}
其他:
输入辅助代码:
package com.nalan.acm.nowoffer.mostrecentancestor;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static TreeNode build(String[] array) {
TreeNode root = new TreeNode();
root.val = Integer.parseInt(array[0].trim());
List<TreeNode> list = new ArrayList();
List<TreeNode> newList;
list.add(root);
for (int arrayIdx = 1; arrayIdx < array.length; list = newList) {
newList = new ArrayList();
for (int j = 0; j < list.size(); j++) {
TreeNode parent = list.get(j);
if (arrayIdx >= array.length) {
break;
}
// left
String value = array[arrayIdx].trim();
if (!value.equals("#")) {
TreeNode p = new TreeNode();
p.val = Integer.valueOf(value);
parent.left = p;
newList.add(p);
}
arrayIdx++;
//right
if (arrayIdx >= array.length) {
break;
}
value = array[arrayIdx].trim();
if (!value.equals("#")) {
TreeNode p = new TreeNode();
p.val = Integer.valueOf(value);
parent.right = p;
newList.add(p);
}
arrayIdx++;
}
}
return root;
}
static public void main(String[] args) {
Scanner s = new Scanner(System.in);
String line = s.nextLine();
String[] a = line.split("[}\\]]+");
String[] array = a[0].replace("[", "").replace("{", "").split(",");
TreeNode root = build(array);
String[] oArr = a[1].replaceFirst(",", "").split(",");
int o1 = Integer.valueOf(oArr[0].trim());
int o2 = Integer.valueOf(oArr[1].trim());
int ret = new Solution().lowestCommonAncestor(root, o1, o2);
System.out.println(ret);
}
}