二叉树有很多不同的算法,但是只要是涉及到二叉树算法的,绝大多数都可以套用一个固定的模板,写起来非常的爽。而且,算法越是复杂,模板越是显示威力
模板:
//套路类,辅助收集树的信息. 这个辅助类非常重要,可以封装各种各样的信息
static class Info {
定义各种需要的变量
}
//套路入口方法
public int mainMethod (Node head)
{
if (head == null) {
return 0;
}
return process(head).height;
}
//套路核心方法
public Info process(Node node)
{
//步骤1: 套路写法
if (node == null) {
return new Info(0);
}
Info leftInfo = process(node.left);
Info rightInfo = process(node.right);
//步骤2: 不同业务场景需要处理不同的业务逻辑
//步骤3: 套路写法
return new Info(height + 1);
}
算法一:给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最大深度 3
普通实现:
package code1.code_03;
/**
* https://leetcode.cn/problems/maximum-depth-of-binary-tree
*/
public class Code04_MaxDepthOfBinaryTree {
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public static int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
public static void main(String[] args) {
}
}
套用模板实现:
package code03.二叉树_02;
/**
* 给定一个二叉树,找出其最大深度。
* 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
* 说明: 叶子节点是指没有子节点的节点。
* 示例:
* 给定二叉树 [3,9,20,null,null,15,7],
*
* 3
* / \
* 9 20
* / \
* 15 7
* 返回它的最大深度 3
*/
public class Code04_TreeHeight {
static class Node {
int val;
Node left;
Node right;
Node(int val) {
this.val = val;
}
}
//套路类,辅助收集树的信息. 这个辅助类非常重要,可以封装各种各样的信息
static class Info {
int height;
Info (int height) {
this.height = height;
}
}
//套路入口方法
public int maxDepth (Node head)
{
if (head == null) {
return 0;
}
return process(head).height;
}
//套路核心方法
public Info process(Node node)
{
//步骤1: 套路写法
if (node == null) {
return new Info(0);
}
Info leftInfo = process(node.left);
Info rightInfo = process(node.right);
//步骤2: 不同业务场景需要处理不同的业务逻辑
int height = 0;
if (leftInfo != null) {
height = Math.max(leftInfo.height, height);
}
if (rightInfo != null) {
height = Math.max(rightInfo.height, height);
}
//步骤3: 套路写法
return new Info(height + 1);
}
public static void main(String[] args) {
Code04_TreeHeight test = new Code04_TreeHeight();
Node node = new Node(3);
node.left = new Node(9);
node.right = new Node(20);
node.left.left = new Node(11);
node.left.right = new Node(13);
node.right.right = new Node(18); //到此处,树的高度为3
node.right.right.right = new Node(19); //到此处, 树的高度为4
int height = test.maxDepth(node);
System.out.println("树的高度为 :" + height);
}
}
算法二:给定一棵二叉树的头节点head,返回这颗二叉树是不是满二叉树 。
回顾一下什么叫满二叉树,在一棵二叉树中, 所有的分支节点都存在左子树和右子树,并且所有叶子节点在同一层上, 这样的二叉树就是满二叉树
普通实现:
package code03.二叉树_02;
import java.util.LinkedList;
import java.util.Queue;
import java.util.zip.CheckedInputStream;
/**
* 在一棵二叉树中, 所有的分支节点都存在左子树和右子树,并且所有叶子节点在同一层上
* 这样的二叉树就是满二叉树
*/
public class Code05_FullTree {
static class Node {
int val;
Node left;
Node right;
Node(int val) {
this.val = val;
}
}
//获取树的高度
public int maxDepth(Node root) {
if (root == null) {
return 0;
}
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
//获取整颗树的节点数
public int nodes(Node node)
{
if (node == null) {
return 0;
}
Queue<Node> queue = new LinkedList<>();
queue.add(node);
int ans = 0;
while (!queue.isEmpty()) {
Node child = queue.poll();
if (child.left != null) {
queue.add(child.left);
}
if (child.right != null) {
queue.add(child.right);
}
ans++;
}
return ans;
}
public boolean isFullTree (Node node) {
if (node == null) {
return true;
}
int heght = maxDepth(node);
int nodeSize = nodes(node);
//
/**
* 根据二叉树的性质,当二叉树的高度为k时
* 那么整颗二叉树节点数最多为 2^k - 1
* 因为此题判断是的满二叉树,因此判断节点个数即可
*/
int size = (int) Math.pow(2, heght)-1;
return nodeSize == size;
}
public static void main(String[] args) {
Node node = new Node(3);
node.left = new Node(9);
node.right = new Node(20);
//node.left.left = new Node(11);
//node.left.right = new Node(13);
// node.right.right = new Node(18); //到此处,树的高度为3
//node.right.right.right = new Node(19); //到此处, 树的高度为4
Code05_FullTree test = new Code05_FullTree();
boolean isFullTree = test.isFullTree(node);
System.out.println(isFullTree);
}
}
套用模板实现:
package code03.二叉树_02;
/**
* 在一棵二叉树中, 所有的分支节点都存在左子树和右子树,并且所有叶子节点在同一层上
* 这样的二叉树就是满二叉树
*/
public class Code05_01_FullTree {
static class Node {
int val;
Node left;
Node right;
Node(int val) {
this.val = val;
}
}
//套路类,辅助收集树的信息. 这个辅助类非常重要,可以封装各种各样的信息
static class Info {
int height;
boolean isFullTree;
Info (int height, boolean isFull) {
this.height = height;
isFullTree = isFull;
}
}
//套路入口方法
public boolean isFullTree (Node head)
{
//我们默认,空树也是满二叉树
if (head == null) {
return true;
}
return process(head).isFullTree;
}
public Info process(Node node)
{
if (node == null) {
return new Info(0, true);
}
Info leftInfo = process(node.left);
Info rightInfo = process(node.right);
//判断左、右子树是否是满二叉树, 有一个不是满二叉树,直接返回
boolean isFullTree = leftInfo.isFullTree && rightInfo.isFullTree && leftInfo.height == rightInfo.height;
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
return new Info(height, isFullTree);
}
public static void main(String[] args) {
Node node = new Node(3);
node.left = new Node(9);
node.right = new Node(20);
node.left.left = new Node(11);
node.left.right = new Node(13);
// node.right.right = new Node(18); //到此处,树的高度为3
//node.right.right.right = new Node(19); //到此处, 树的高度为4
Code05_01_FullTree test = new Code05_01_FullTree();
boolean isFullTree = test.isFullTree(node);
System.out.println(isFullTree);
}
}
算法三:给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
package code03.二叉树_02;
/**
* https://leetcode.cn/problems/balanced-binary-tree/
* 给定一个二叉树,判断它是否是高度平衡的二叉树。
*
* 本题中,一棵高度平衡二叉树定义为:
*
* 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
*/
public class Code06_BalanceBinaryTree
{
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public static class Info {
public boolean isBalanced;
public int height;
public Info(boolean i, int h) {
isBalanced = i;
height = h;
}
}
public boolean isBalanced(TreeNode root) {
return process(root).isBalanced;
}
public static Info process(TreeNode root) {
//边界值
if (root == null) {
return new Info(true, 0);
}
Info leftInfo = process(root.left);
Info rightInfo = process(root.right);
//当前节点的高度
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
boolean isBalanced = leftInfo.isBalanced && rightInfo.isBalanced
&& Math.abs(leftInfo.height - rightInfo.height) < 2;
return new Info(isBalanced, height);
}
public static void main(String[] args) {
Code06_BalanceBinaryTree tree = new Code06_BalanceBinaryTree();
TreeNode node1 = tree.new TreeNode(3);
TreeNode left2 = tree.new TreeNode(9);
TreeNode righ2 = tree.new TreeNode(20);
node1.left = left2;
node1.right = righ2;
TreeNode left3 = tree.new TreeNode(15);
TreeNode righ3 = tree.new TreeNode(7);
righ2.left = left3;
righ2.right = righ3;
System.out.println(tree.isBalanced(node1));
}
}
算法四: 给定一棵二叉树的头节点head,任何两个节点之间都存在距离,返回整棵二叉树的最大距离。解释: 距离就是这2个节点间的数量,包含这两个节点本身
package code03.二叉树_02;
/**
* 给定一棵二叉树的头节点head,任何两个节点之间都存在距离,
* 返回整棵二叉树的最大距离
*
* 解释: 距离就是这2个节点间的数量,包含这两个节点本身
*/
public class Code07_MaxDIstance {
static class Node {
int val;
Node left;
Node right;
Node(int val) {
this.val = val;
}
}
//套路类,辅助收集树的信息. 这个辅助类非常重要,可以封装各种各样的信息
static class Info {
int height;
int maxDistance; //记录当前节点的最大
Info (int height, int maxDistance) {
this.height = height;
this.maxDistance = maxDistance;
}
}
public int getMaxDistance (Node node)
{
return process(node).maxDistance;
}
public Info process(Node node)
{
if (node == null) {
return new Info(0,0);
}
Info leftInto = process(node.left);
Info rightInfo = process(node.right);
//当前节点的高度
int height = Math.max(leftInto.height, rightInfo.height) + 1;
/**
* 只经过左子树就产生最大距离, 距離為6
* 3
* / \
* 4 5
* / \
* 41 42
* \ /
* 412 421
* \
* 4212
* 产生最大距离的路径为 412 -> 41 -> 4 -> 42 ->421 -> 4212
*/
int leftDistance = leftInto.maxDistance;
/**
* 只经过左子树就产生最大距离, 距離為6
* 3
* / \
* 4 5
* / \
* 51 52
* \ /
* 512 521
* \
* 5212
* 产生最大距离的路径为 4512 -> 51 -> 5 -> 52 ->521 -> 5212
*/
int rightDistance = rightInfo.maxDistance;
/**
* 只经过左子树就产生最大距离, 距離為5
* 3
* / \
* 4 5
* / \
* 41 42
* \
* 412
*
* 产生最大距离的路径为 412 -> 41 -> 4 -> 3 ->5
*/
int totalDistance = leftInto.height + rightInfo.height + 1;
//此处就是针对上方出现的3种情况做判断,找出怎么样组合才能产生最大距离
int maxDistance = Math.max(Math.max(leftDistance, rightDistance), totalDistance);
return new Info(height,maxDistance);
}
public static void main(String[] args) {
Code07_MaxDIstance test = new Code07_MaxDIstance();
Node node = new Node(3);
node.left = new Node(4);
node.right = new Node(5);
//距离为3
System.out.println("当前树的最大距离为 " + test.getMaxDistance(node));
node.left.left = new Node(41);
node.left.right = new Node(42);
node.left.left.right = new Node(412);
node.left.right.left = new Node(421);
//正确答案为5
System.out.println("当前树的最大距离为 " + test.getMaxDistance(node));
node.right.right = new Node(52);
node.right.right.right = new Node(522);
node.right.right.right.left = new Node(5221);
//正确答案为8
System.out.println("当前树的最大距离为 " + test.getMaxDistance(node));
}
}
算法五:判断二叉树是否是搜索二叉树
搜索二叉树 二叉排序树 二叉查找树 都是同一个概念,它或者是一颗空树,或者具有以下性质:
1)若它的左子树不为空, 则左子树上的所有节点值均小于它的根节点
2)若它的右子树不为空, 则右子树上的所有节点值均大于它的根节点
3)它的左、右子树也分别是搜索二叉树
package code03.二叉树_02;
/**
*判断二叉树是否是搜索二叉树
*
* 搜索二叉树 二叉排序树 二叉查找树 都是同一个概念,它或者
* 是一颗空树,或者具有以下性质:
* 1)若它的左子树不为空, 则左子树上的所有节点值均小于它的根节点
* 2)若它的右子树不为空, 则右子树上的所有节点值均大于它的根节点
* 3)它的左、右子树也分别为二叉排序树
*/
public class Code08_SearchBST {
static class Node {
int val;
Node left;
Node right;
Node(int val) {
this.val = val;
}
}
//套路类,辅助收集树的信息. 这个辅助类非常重要,可以封装各种各样的信息
static class Info {
boolean ishBST;
int max;
int min;
Info (boolean ishBST, int max, int min) {
this.ishBST = ishBST;
this.max = max;
this.min = min;
}
}
public boolean isSearchBST (Node node)
{
if (node == null) {
return true;
}
return process(node).ishBST;
}
public Info process (Node node)
{
if (node == null) {
return null;
}
Info leftInfo = process(node.left);
Info rightInfo = process(node.right);
//此处的max和min是为了返回上一侧使用
//返回后,当前成就成了子节点。子节点也需要
//是一颗搜索二叉树,即左节点值都小于根节点
//有节点值都大于根节点
int max = node.val;
int min = node.val;
//左树不为空
if (leftInfo != null) {
max = Math.max(leftInfo.max, max);
min = Math.min(leftInfo.min, min);
}
if(rightInfo != null) {
max = Math.max(rightInfo.max, max);
min = Math.min(rightInfo.min, min);
}
boolean isBST = true;
//它的左子树不为空, 则左子树上的所有节点值均小于它的根节点
//它的左、右子树也分别为二叉排序树(搜索二叉树)
if(leftInfo != null && (!leftInfo.ishBST || leftInfo.max >= node.val)) {
isBST = false;
}
if(rightInfo != null && (!rightInfo.ishBST || rightInfo.min <= node.val)) {
isBST = false;
}
return new Info(isBST, max, min);
}
public static void main(String[] args) {
Code08_SearchBST test = new Code08_SearchBST();
Node node = new Node(40);
node.left = new Node(30);
node.right = new Node(50);
//true
System.out.println("搜索二叉树 :" + test.isSearchBST(node));
node.left.left = new Node(25);
node.left.right = new Node(33);
node.left.left.left = new Node(22);
node.left.left.right = new Node(27);
//true
System.out.println("搜索二叉树 :" + test.isSearchBST(node));
node.right.left = new Node(49);
node.right.right = new Node(48);
//false
System.out.println("搜索二叉树 :" + test.isSearchBST(node));
}
}
算法六: 给定一棵二叉树的头节点head, 返回这颗二叉树中最大的二叉搜索子树的大小
在算法五中我们刚刚实现了判断一颗树是否是二叉搜索树,而此题则整颗树可能是,也可能不是搜索二叉树。如果整颗树不是搜索二叉树,我们需要找到最大的子搜索二叉树节点数,如果整棵树是二叉搜索树,则返回整棵树的节点
package code03.二叉树_02;
/**
* 给定一棵二叉树的头节点head,
* 返回这颗二叉树中最大的二叉搜索子树的大小
*
* 搜索二叉树 二叉排序树 二叉查找树 都是同一个概念,它或者
* 是一颗空树,或者具有以下性质:
* 1)若它的左子树不为空, 则左子树上的所有节点值均小于它的根节点
* 2)若它的右子树不为空, 则右子树上的所有节点值均大于它的根节点
* 3)它的左、右子树也分别为二叉排序树
*/
public class Code09_SearchSubBST {
static class Node {
int val;
Node left;
Node right;
Node(int val) {
this.val = val;
}
}
//套路类,辅助收集树的信息. 这个辅助类非常重要,可以封装各种各样的信息
static class Info {
boolean ishBST;
int subBSTSize;
int max;
int min;
Info (boolean ishBST, int max, int min, int subBSTSize) {
this.ishBST = ishBST;
this.max = max;
this.min = min;
this.subBSTSize = subBSTSize;
}
}
public int subMaxBST (Node node)
{
if (node == null) {
return 0;
}
return process(node).subBSTSize;
}
public Info process (Node node)
{
if (node == null) {
return null;
}
Info leftInfo = process(node.left);
Info rightInfo = process(node.right);
//此处的max和min是为了返回上一侧使用
//返回后,当前成就成了子节点。子节点也需要
//是一颗搜索二叉树,即左节点值都小于根节点
//有节点值都大于根节点
int max = node.val;
int min = node.val;
//左树不为空
if (leftInfo != null) {
max = Math.max(leftInfo.max, max);
min = Math.min(leftInfo.min, min);
}
if(rightInfo != null) {
max = Math.max(rightInfo.max, max);
min = Math.min(rightInfo.min, min);
}
boolean isBST = true;
//左子搜索二叉树的节点数. 如果返回上一层无法组成新的二叉搜索树,则会一直
//保留之前的二叉搜索树
int leftSubBSTSize = leftInfo != null ? leftInfo.subBSTSize : 0;
//右子搜索二叉树的节点数
int rightSubBSTSize = rightInfo != null ? rightInfo.subBSTSize : 0;
//检查当前节点,左节点,右节点是否可以组成新的二叉搜索树
if(leftInfo != null && (!leftInfo.ishBST || leftInfo.max >= node.val)) {
isBST = false;
}
if(rightInfo != null && (!rightInfo.ishBST || rightInfo.min <= node.val)) {
isBST = false;
}
int subBSTSize = 0;
//如果能够组成新的二叉搜索树
if (isBST) {
subBSTSize = leftSubBSTSize + rightSubBSTSize + 1;
}
else {
//不能的话,左、右二叉搜索树选大的
subBSTSize = Math.max(leftSubBSTSize, rightSubBSTSize);
}
return new Info(isBST, max, min, subBSTSize);
}
public static void main(String[] args) {
Code09_SearchSubBST test = new Code09_SearchSubBST();
Node node = new Node(40);
node.left = new Node(20);
node.right = new Node(80);
//3
System.out.println("搜索二叉树 :" + test.subMaxBST(node));
node.left.left = new Node(26);
node.left.right = new Node(30);
node.left.left.left = new Node(19);
node.left.left.right = new Node(27);
node.left.right.left = new Node(22);
node.left.right.right = new Node(38);
node.left.right.left.left = new Node(21);
node.left.right.left.right = new Node(23);
//7
System.out.println("搜索二叉树 :" + test.subMaxBST(node));
}
}
继续针对算法六进行小范围的眼神题目
算法七 :给定一棵二叉树的头节点head,返回这颗二叉树中最大的二叉搜索子树的头节点
package code03.二叉树_02;
/**
* 给定一棵二叉树的头节点head,
* 返回这颗二叉树中最大的二叉搜索子树的头节点
*
* 搜索二叉树 二叉排序树 二叉查找树 都是同一个概念,它或者
* 是一颗空树,或者具有以下性质:
* 1)若它的左子树不为空, 则左子树上的所有节点值均小于它的根节点
* 2)若它的右子树不为空, 则右子树上的所有节点值均大于它的根节点
* 3)它的左、右子树也分别为二叉排序树
*/
public class Code10_SearchSubBST {
static class Node {
int val;
Node left;
Node right;
Node(int val) {
this.val = val;
}
}
//套路类,辅助收集树的信息. 这个辅助类非常重要,可以封装各种各样的信息
static class Info {
boolean ishBST;
int subBSTSize;
int max;
int min;
Node head;
Info (boolean ishBST, int max, int min, int subBSTSize, Node head) {
this.ishBST = ishBST;
this.max = max;
this.min = min;
this.subBSTSize = subBSTSize;
this.head = head;
}
}
public Node subHeadBST (Node node)
{
if (node == null) {
return node;
}
return process(node).head;
}
public Info process (Node node)
{
if (node == null) {
return null;
}
Info leftInfo = process(node.left);
Info rightInfo = process(node.right);
//此处的max和min是为了返回上一侧使用
//返回后,当前成就成了子节点。子节点也需要
//是一颗搜索二叉树,即左节点值都小于根节点
//有节点值都大于根节点
int max = node.val;
int min = node.val;
//左树不为空
if (leftInfo != null) {
max = Math.max(leftInfo.max, max);
min = Math.min(leftInfo.min, min);
}
if(rightInfo != null) {
max = Math.max(rightInfo.max, max);
min = Math.min(rightInfo.min, min);
}
boolean isBST = true;
//左子搜索二叉树的节点数. 如果返回上一层无法组成新的二叉搜索树,则会一直
//保留之前的二叉搜索树
int leftSubBSTSize = leftInfo != null ? leftInfo.subBSTSize : 0;
//右子搜索二叉树的节点数
int rightSubBSTSize = rightInfo != null ? rightInfo.subBSTSize : 0;
//检查当前节点,左节点,右节点是否可以组成新的二叉搜索树
if(leftInfo != null && (!leftInfo.ishBST || leftInfo.max >= node.val)) {
isBST = false;
}
if(rightInfo != null && (!rightInfo.ishBST || rightInfo.min <= node.val)) {
isBST = false;
}
int subBSTSize = 0;
Node head = null;
//如果能够组成新的二叉搜索树
if (isBST) {
subBSTSize = leftSubBSTSize + rightSubBSTSize + 1;
//如果当前节点和左右子树可以组成新的搜索二叉子树, 则当前节点为新的头结点
head = node;
}
else {
//不能的话,左、右二叉搜索树选大的
subBSTSize = Math.max(leftSubBSTSize, rightSubBSTSize);
head = leftSubBSTSize > rightSubBSTSize ? leftInfo.head : rightInfo.head;
}
return new Info(isBST, max, min, subBSTSize, head);
}
public static void main(String[] args) {
Code10_SearchSubBST test = new Code10_SearchSubBST();
Node node = new Node(40);
node.left = new Node(20);
node.right = new Node(80);
//头结点为40
Node head = test.subHeadBST(node);
System.out.println(head.val);
//node.left.left = new Node(26);
node.left.left = new Node(18);
node.left.right = new Node(30);
node.left.left.left = new Node(15);
node.left.left.right = new Node(27);
//node.left.right.left = new Node(22);
node.left.right.left = new Node(22);
node.left.right.right = new Node(38);
node.left.right.left.left = new Node(21);
node.left.right.left.right = new Node(23);
//头结点为30
head = test.subHeadBST(node);
System.out.println(head.val);
//把节点值26改成18, 则新的头结点则是30
head = test.subHeadBST(node);
System.out.println(head.val);
//把节点值22改成31, 则新的头结点则是18
head = test.subHeadBST(node);
System.out.println(head.val);
}
}
继续套用模板来解决最小公共祖先的问题
算法八: 给定一棵二叉树的头节点head,和另外两个节点a和b。返回a和b的最低公共祖先。解释一下什么叫公共祖先,公共祖先就是这两个节点第一次连接在一起的节点。
解题思路:
1)首先得找到这两个节点
2)第一次找到以后,记录下这个节点,逐层往上返回即可
package code03.二叉树_02;
/**
* 给定一棵二叉树的头节点head,和另外两个节点a和b。返回a和b的最低公共祖先
*/
public class Code11_MinSameParents {
static class Node {
int val;
Node left;
Node right;
Node(int val) {
this.val = val;
}
}
//套路类,辅助收集树的信息. 这个辅助类非常重要,可以封装各种各样的信息
static class Info {
boolean findA;
boolean findB;
Node minParents; //最小公共祖先
Info (Node minParents, boolean findA, boolean findB) {
this.minParents = minParents;
this.findA = findA;
this.findB = findB;
}
}
public Node minParents(Node head, Node a, Node b)
{
if (head == null || a == null || b == null) {
return null;
}
return process(head, a, b).minParents;
}
public Info process(Node head, Node a, Node b)
{
if (head == null) {
return new Info(null, false, false);
}
Info leftInfo = process(head.left, a, b);
Info rightInfo = process(head.right, a, b);
Node minParent = leftInfo.minParents;
//判断最小公共父节点,首先得找到这两个节点
boolean findA = head == a || leftInfo.findA || rightInfo.findA;
boolean findB = head == b || leftInfo.findB || rightInfo.findB;
//如果同时找到了a和b节点,那么检查他们的最小公共
//父节点是否已经找到,没有找到的话则记录下来
//如果已经找到最小公共祖先,则一直返回
if (findA && findB && minParent == null) {
minParent = head;
}
return new Info(minParent, findA, findB);
}
public static void main(String[] args)
{
Code11_MinSameParents test = new Code11_MinSameParents();
Node node = new Node(0);
Node node1 = new Node(11);
Node node2 = new Node(22);
Node node3 = new Node(44);
Node node4 = new Node(16);
Node node5 = new Node(32);
Node node6 = new Node(67);
Node node7= new Node(88);
Node node8 = new Node(76);
node.left = node1; node.right = node2;
node1.left = node3; node1.right = node4;
node3.left = node5;
node5.right = node6;
node2.right = node7; node7.left = node8;
/**
* 构造一颗二叉树
* 0
* / \
* 11 22
* / \ \
* 44 16 88
* / /
* 32 76
* \
* 67
*
*/
//node4对应16, node6对应67. 应该找到的最小公共节点值为11
Node minP = test.minParents(node, node4, node6);
System.out.println(minP != null ? minP.val : null);
//node6对应67, node8对应76. 应该找到的最小公共节点值为0
minP = test.minParents(node, node8, node6);
System.out.println(minP != null ? minP.val : null);
//测试两个相同节点 node5对应32,应该找到32
minP = test.minParents(node, node5, node5);
System.out.println(minP != null ? minP.val : null);
//测试一个子节点,一个父节点.
// 父节点node3对应44,子节点node5对应32,应该找到node3即值44
minP = test.minParents(node, node5, node3);
System.out.println(minP != null ? minP.val : null);
}
}
相信看了这么多道题目以后,是否非常认可我的模板套路,越是复杂的二叉树业务,模板套路越是能够发挥出强大的威力。说是万能模板,肯定是夸张了,但是这种模板化的写法确实非常的实用,能够适应很多二叉树的算法,抓紧掌握吧