代码随想录day20|最大二叉树. 合并二叉树. 二叉搜索树中的搜索. 验证二叉搜索树
最大二叉树
给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:
- 创建一个根节点,其值为
nums中的最大值。 - 递归地在最大值 左边 的 子数组前缀上 构建左子树。
- 递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums 构建的 最大二叉树 。
分析 找到最值index后构造root. 左节点从[leftindex 到最值index], 右节点从[最值index+1,rightIndex]
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return constructMaximumBinaryTree1(nums,0,nums.length);
}
private TreeNode constructMaximumBinaryTree1(int[] nums, int leftIndex, int rightIndex){
if(rightIndex-leftIndex<1){
return null;
}
int maxIndex=leftIndex;
int maxVal=nums[maxIndex];
if(rightIndex-leftIndex==1){
return new TreeNode(maxVal);
}
for (int i =leftIndex+1;i<rightIndex;i++){
if(nums[i]>maxVal){
maxVal=nums[i];
maxIndex=i;
}
}
TreeNode root=new TreeNode(maxVal);
root.left=constructMaximumBinaryTree1(nums,leftIndex,maxIndex);
root.right=constructMaximumBinaryTree1(nums,maxIndex+1,rightIndex);
return root;
}
}
合并二叉树
给你两棵二叉树: root1 和 root2 。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
分析 按照递归三部曲来解决:
- 确定递归函数的参数和返回值:
首先要合入两个二叉树,那么参数至少是要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点。
- 确定终止条件:
因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。
反过来如果t2 == NULL,那么两个数合并就是t1(如果t1也为NULL也无所谓,合并之后就是NULL)。
if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2
if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1
- 确定单层递归的逻辑:
单层递归的逻辑就比较好写了,这里我们重复利用一下t1这个树,t1就是合并之后树的根节点(就是修改了原来树的结构)。
那么单层递归中,就要把两棵树的元素加到一起。t1就是合并之后的根节点。
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
return mergeTree(root1,root2);
}
private TreeNode mergeTree(TreeNode root1,TreeNode root2){
if(root1==null) return root2;
if(root2==null) return root1;
root1.val+=root2.val;
root1.left=mergeTree(root1.left,root2.left);
root1.right=mergeTree(root1.right,root2.right);
return root1;
}
}
二叉搜索树中的搜索
给定二叉搜索树(BST)的根节点 root 和一个整数值 val。
你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。
分析
- 确定递归函数的参数和返回值
递归函数的参数传入的就是根节点和要搜索的数值,返回的就是以这个搜索数值所在的节点。
- 确定终止条件
如果root为空,或者找到这个数值了,就返回root节点。
- 确定单层递归的逻辑
看看二叉搜索树的单层递归逻辑有何不同。
因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。
如果root->val > val,搜索左子树,如果root->val < val,就搜索右子树,最后如果都没有搜索到,就返回NULL。
class Solution {
// 递归,普通二叉树
public TreeNode searchBST(TreeNode root, int val) {
if (root == null || root.val == val) {
return root;
}
TreeNode left = searchBST(root.left, val);
if (left != null) {
return left;
}
return searchBST(root.right, val);
}
}
class Solution {
// 递归,利用二叉搜索树特点,优化
public TreeNode searchBST(TreeNode root, int val) {
if (root == null || root.val == val) {
return root;
}
if (val < root.val) {
return searchBST(root.left, val);
} else {
return searchBST(root.right, val);
}
}
}
验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
class Solution { // 递归 TreeNode max; public boolean isValidBST(TreeNode root) { if (root == null) { return true; } // 左 boolean left = isValidBST(root.left); if (!left) { return false; } // 中 if (max != null && root.val <= max.val) { return false; } max = root; // 右 boolean right = isValidBST(root.right); return right; } }

浙公网安备 33010602011771号