-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathP236.java
More file actions
157 lines (126 loc) · 5.11 KB
/
P236.java
File metadata and controls
157 lines (126 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
236. 二叉树的最近公共祖先
https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
https://leetcode-cn.com/explore/interview/card/top-interview-questions-hard/57/trees-and-graphs/139/
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/15/binarytree.png
示例 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 为不同节点且均存在于给定的二叉树中。
*/
import java.util.*;
public class P236 {
public static void main(String[] args) {
TreeNode root = stringToTreeNode("[3,5,1,6,2,0,8,null,null,7,4]");
prettyPrintTree(root);
System.out.println(new Solution().lowestCommonAncestor(root, root.left, root.left.right.right).val);
}
static class Solution {
// 递归查找A和B, 找到A和B第一次在同一棵子树中的子树根节点即是LCA。
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}
if (root == p || root == q) { // 在root中找pq
return root;
}
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
// 若搜索结果均非空, 说明两个节点分别位于左右子树之中, LCA则为root
if (left != null && right != null) return root;
// 若只有一个结果为空, 则LCA是另一个非空的节点
if (left != null) return left;
if (right != null) return right;
// 若结果均空, 则返回NULL
return null;
}
}
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public static String treeNodeToString(TreeNode root) {
if (root == null) {
return "[]";
}
String output = "";
Queue<TreeNode> nodeQueue = new LinkedList<>();
nodeQueue.add(root);
while(!nodeQueue.isEmpty()) {
TreeNode node = nodeQueue.remove();
if (node == null) {
output += "null, ";
continue;
}
output += String.valueOf(node.val) + ", ";
nodeQueue.add(node.left);
nodeQueue.add(node.right);
}
return "[" + output.substring(0, output.length() - 2) + "]";
}
public static TreeNode stringToTreeNode(String input) {
input = input.trim();
input = input.substring(1, input.length() - 1);
if (input.length() == 0) {
return null;
}
String[] parts = input.split(",");
String item = parts[0];
TreeNode root = new TreeNode(Integer.parseInt(item));
Queue<TreeNode> nodeQueue = new LinkedList<>();
nodeQueue.add(root);
int index = 1;
while(!nodeQueue.isEmpty()) {
TreeNode node = nodeQueue.remove();
if (index == parts.length) {
break;
}
item = parts[index++];
item = item.trim();
if (!item.equals("null")) {
int leftNumber = Integer.parseInt(item);
node.left = new TreeNode(leftNumber);
nodeQueue.add(node.left);
}
if (index == parts.length) {
break;
}
item = parts[index++];
item = item.trim();
if (!item.equals("null")) {
int rightNumber = Integer.parseInt(item);
node.right = new TreeNode(rightNumber);
nodeQueue.add(node.right);
}
}
return root;
}
public static void prettyPrintTree(TreeNode node, String prefix, boolean isLeft) {
if (node == null) {
System.out.println("Empty tree");
return;
}
if (node.right != null) {
prettyPrintTree(node.right, prefix + (isLeft ? "│ " : " "), false);
}
System.out.println(prefix + (isLeft ? "└── " : "┌── ") + node.val);
if (node.left != null) {
prettyPrintTree(node.left, prefix + (isLeft ? " " : "│ "), true);
}
}
public static void prettyPrintTree(TreeNode node) {
prettyPrintTree(node, "", true);
}
}