题目链接:654. 最大二叉树
通过递归找到数组的最大值,及其位置,然后用最大值创建根节点。
再利用递归,用最大值左边子数组前缀上构建左子树,以及用最大值右边子数组后缀构建右子树。
最后将根节点返回。
代码如下:
class Solution {
public TreeNode travel(int[] nums, int begin, int end) {//参数左闭右开
if(begin >= end) return null;//如果切割数组的起始位置大于等于结束位置说明没有子树,返回null
int maxIndex = begin;//记录子数组最大值的下标
int maxValue = nums[begin];//记录子数组的最大值
for(int i = begin + 1; i < end; i++) {//找到并记录子数组的最大值及下标
if(nums[i] > maxValue) {
maxIndex = i;
maxValue = nums[i];
}
}
TreeNode root = new TreeNode(maxValue);//用最大值创建根节点
root.left = travel(nums, begin, maxIndex);//通过递归创建左子树,
root.right = travel(nums, maxIndex + 1, end);//通过递归创建右子树
return root;//返回根节点
}
public TreeNode constructMaximumBinaryTree(int[] nums) {
return travel(nums, 0, nums.length);
}
}
题目链接:617. 合并二叉树、
我们利用递归找到两棵树每对节点所对应的位置,然后在进行相应的处理。
如果两颗节点都为空,说明该处节点为空节点。
如果两个节点都不为空,将两个节点的值进行相加,创建合并后该处节点的值,再递归创建左右子树。
如果一个节点为空一个节点不为空,则利用非空节点的值创建合并后该处节点的值,在递归创建左右子树。
代码如下:
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if(root1 == null && root2 == null) return null;//如果两颗树对应的节点都为空,返回空
if(root1 != null && root2 != null) {//如果两颗树对应的节点都不为空,将root1节点的值加上root2节点的值,然后再通过递归创建root1左右子树(我们要返回的是root1)
root1.val += root2.val;
root1.left = mergeTrees(root1.left, root2.left);
root1.right = mergeTrees(root1.right, root2.right);
}else if(root1 != null) {//如果root1节点不为空但是root2节点为空,利用递归创建root1的左右子树,递归(传入的参数是root1的左右子节点和null)
root1.left = mergeTrees(root1.left, null);
root1.right = mergeTrees(root1.right, null);
}else {//如果root1为空,root2不为空,将root2赋值给root1,然后再利用递归创建root1的左右子树
root1 = root2;
root1.left = mergeTrees(root1.left, null);
root1.right = mergeTrees(root1.right,null);
}
return root1;//最后返回root1
}
}
题目链接:700. 二叉搜索树中的搜索
这道题很简单,利用递归。
如果当前节点为空,说明不存在值等于目标值的节点,返回null。
如果当前节点的值等于目标值,则将该节点返回。
如果当前节点的值小于目标值,说明目标值可能再当前节点的右子树,利用递归对右子树进行搜索。
如果当前节点的值大于目标值,说明目标值可能在当前节点的左子树,利用递归对左子树进行搜索。
代码如下:
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if(root == null) return null;
if(root.val == val) return root;
else if(val > root.val) return searchBST(root.right, val);
else return searchBST(root.left, val);
}
}
题目链接:98. 验证二叉搜索树
根据当前节点的值,左子树最大节点的值,右子树最小节点的值,的不同情况进行判断。
如果当前节点为空返回true,否则找出左子树的最大节点,右子树的最小节点。
如果最大节点和最小节点都为空,当前子树满足二叉搜索树,返回true。
如果都不为空,验证左子树最大节点的值是否小于当前节点的值,当前节点的值是否小于右子树最小节点的值,然后通过递归验证左右子树是否满足二叉搜索树。
如果一个为空一个不为空,验证当前节点值与不为空的节点的值的大小关系是否满足二叉搜索树,在验证左子树或右子树是否满足二叉搜索树。
代码如下:
class Solution {
public TreeNode leftMax(TreeNode root) {//求出左子树的最大子节点
if(root == null) return null;
if(root.right == null) return root;
else return leftMax(root.right);
}
public TreeNode rightMin(TreeNode root) {//求右子树的最小子节点
if(root == null) return null;
if(root.left == null) return root;
else return rightMin(root.left);
}
public boolean isValidBST(TreeNode root) {
if(root == null) return true;//如果当前节点为空,返回true
TreeNode left = null;
TreeNode right = null;
if(root.left != null) left = leftMax(root.left);//找到左子树的最大子节点
if(root.right != null) right = rightMin(root.right);//找到右子树的最小子节点
if(left == null && right == null) return true;//如果左子树的最大子节点和右子树的最小子节点都为空,符合二叉搜索树,返回true
else if(left != null && right != null) {//如果都不为空,验证左子树最大子节点的值是否小于当前节点的值,当前节点的值是否小于右子树最小节点的值,如果不满足,不是二叉搜索树
boolean cur;
if(left.val < root.val && root.val < right.val) cur = true;
else cur = false;
boolean leftTrue = isValidBST(root.left);//递归左子树是否是二叉搜索树
boolean rightTrue = isValidBST(root.right);//递归右子树是否是二叉搜索树
return cur && leftTrue && rightTrue;//返回三个标记的与值
}else if(left != null) {//如果左子树的最大节点不为空,右子树的最小节点为空,判断最小节点的值是否小于当前节点的值
boolean cur;
if(left.val < root.val) cur = true;
else cur = false;
boolean leftTrue = isValidBST(root.left);//递归左子树是否是二叉搜索树
return cur && leftTrue;//返回两个结果的与值
}else {//同上理
boolean cur;
if(root.val < right.val) cur = true;
else cur = false;
boolean rightTrue = isValidBST(root.right);
return cur && rightTrue;
}
}
}
二叉搜索树,左子树的所有节点的值全小于当前节点的值,右子树的左右节点的值全大于当前节点的值。