热门面试题第15天|最大二叉树 合并二叉树 验证二叉搜索树 二叉搜索树中的搜索

654.最大二叉树

力扣题目地址(opens new window)

给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

  • 二叉树的根是数组中的最大元素。
  • 左子树是通过数组中最大值左边部分构造出的最大二叉树。
  • 右子树是通过数组中最大值右边部分构造出的最大二叉树。

通过给定的数组构建最大二叉树,并且输出这个树的根节点。

示例 :

提示:

给定的数组的大小在 [1, 1000] 之间。

思路:

其实这个最大二叉树的定义和二叉搜索树非常像,我们能想到的是先找到里面最大的节点,将其放在根节点,然后去它的左子树里面寻找,接着去右子树里面寻找,属于前序遍历。

确定递归函数参数以及返回值

java 复制代码
public TreeNode constructMaximumBinaryTree1(int[] nums, int leftIndex, int rightIndex)

我们根据传入的数组,和数组的起始结束节点来确定边界

确定终止条件

java 复制代码
if (rightIndex - leftIndex < 1) {// 没有元素了
            return null;
        }
        if (rightIndex - leftIndex == 1) {// 只有一个元素
            return new TreeNode(nums[leftIndex]);
        }

当没有元素的时候直接退出,只有一个元素的时候直接return即可

确定单层递归的逻辑

java 复制代码
        int maxIndex = leftIndex;// 最大值所在位置
        int maxVal = nums[maxIndex];// 最大值
        for (int i = leftIndex + 1; i < rightIndex; i++) {
            if (nums[i] > maxVal){
                maxVal = nums[i];
                maxIndex = i;
            }
        }
        TreeNode root = new TreeNode(maxVal);
        // 根据maxIndex划分左右子树
        root.left = constructMaximumBinaryTree1(nums, leftIndex, maxIndex);
        root.right = constructMaximumBinaryTree1(nums, maxIndex + 1, rightIndex);
        return root;

通过循环找到最大值,再通过递归左,右,最后return root即可

我们来看完整代码、

java 复制代码
class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return constructMaximumBinaryTree1(nums, 0, nums.length);
    }

    public TreeNode constructMaximumBinaryTree1(int[] nums, int leftIndex, int rightIndex) {
        if (rightIndex - leftIndex < 1) {// 没有元素了
            return null;
        }
        if (rightIndex - leftIndex == 1) {// 只有一个元素
            return new TreeNode(nums[leftIndex]);
        }
        int maxIndex = leftIndex;// 最大值所在位置
        int maxVal = nums[maxIndex];// 最大值
        for (int i = leftIndex + 1; i < rightIndex; i++) {
            if (nums[i] > maxVal){
                maxVal = nums[i];
                maxIndex = i;
            }
        }
        TreeNode root = new TreeNode(maxVal);
        // 根据maxIndex划分左右子树
        root.left = constructMaximumBinaryTree1(nums, leftIndex, maxIndex);
        root.right = constructMaximumBinaryTree1(nums, maxIndex + 1, rightIndex);
        return root;
    }
}

617.合并二叉树

力扣题目链接(opens new window)

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

示例 1:

注意: 合并必须从两个树的根节点开始。

思路:

这道题不难,我们只需要分别对两个数对应同一位置的节点进行比较,并且对节点进行处理就可以,采用那种遍历方式都行

确定递归方法及其参数

java 复制代码
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {

我们只需要两棵树的节点就行

确定终止条件

java 复制代码
if (root1 == null) return root2;
if (root2 == null) return root1;

如果树枝的一部分为空,直接返回另一部分就行了

确定单层递归逻辑

java 复制代码
        root1.val += root2.val;
        root1.left = mergeTrees(root1.left,root2.left);
        root1.right = mergeTrees(root1.right,root2.right);
        return root1;

将两个节点的值相加,然后递归左右节点即可

我们来看完整代码

java 复制代码
class Solution {
    // 递归
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1 == null) return root2;
        if (root2 == null) return root1;

        root1.val += root2.val;
        root1.left = mergeTrees(root1.left,root2.left);
        root1.right = mergeTrees(root1.right,root2.right);
        return root1;
    }
}

700.二叉搜索树中的搜索

力扣题目地址(opens new window)

给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

例如,

在上述示例中,如果要找的值是 5,但因为没有节点值为 5,我们应该返回 NULL。

思路:

我们找到了对应target值的节点之后进行返回操作即可,中间利用二叉搜索树的性质进行查找

确定递归函数及其参数

java 复制代码
public TreeNode searchBST(TreeNode root, int val

传入节点和target值即可

确定终止条件

java 复制代码
if (root == null || root.val == val) {
            return root;
        }

当根节点为空或者我们找到了对应值的节点的时候,我们直接返回就行

确定单层递归逻辑

java 复制代码
if (val < root.val) {
            return searchBST(root.left, val);
        } else {
            return searchBST(root.right, val);
        }

如果root的值比target大,我们就从root的左子树去递归,反之亦然

我们来看完整代码

java 复制代码
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);
        }
    }
}

98.验证二叉搜索树

力扣题目链接(opens new window)

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

思路 :二叉搜索树 左节点小于中间节点小于右节点,注意是所有左节点 下面这个情况是不符合的

不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了

写出了类似这样的代码:

java 复制代码
if (root->val > root->left->val && root->val < root->right->val) {
    return true;
} else {
    return false;
}

确定终止条件

java 复制代码
if (root == NULL) return true;

递归到空节点,我们返回true,因为空节点也是二叉搜索树

确定单层递归逻辑

java 复制代码
 boolean left = isValidBST(root.left);
        
        if (pre != null && pre.val >= root.val) return false;
        pre = root; // 记录前一个节点
        
        boolean right = isValidBST(root.right);
        
        return left && right;

左中右,中序遍历找到最左边,最小的节点值,然后一层一层返回去判断当前节点值是否大于pre,一旦有一个节点不满足,就会返回false 然后向上返回回去。

我们可以通过图示理解

java 复制代码
    5
   / \
  3   7
 / \   \
1   4   8
isValidBST(5)
├── left = isValidBST(3)
│   ├── left = isValidBST(1)
│   │   ├── left = isValidBST(NULL) → true
│   │   ├── pre = NULL → 1
│   │   └── right = isValidBST(NULL) → true
│   │   └── 返回:true && true = true
│   ├── pre = 1 → 3
│   └── right = isValidBST(4)
│       ├── left = isValidBST(NULL) → true
│       ├── pre = 3 → 4
│       └── right = isValidBST(NULL) → true
│       └── 返回:true && true = true
│   └── 返回:true && true = true
├── pre = 4 → 5
└── right = isValidBST(7)
    ├── left = isValidBST(NULL) → true
    ├── pre = 5 → 7
    └── right = isValidBST(8)
        ├── left = isValidBST(NULL) → true
        ├── pre = 7 → 8
        └── right = isValidBST(NULL) → true
        └── 返回:true && true = true
    └── 返回:true && true = true
└── 返回:true && true = true

我们来看完整代码

java 复制代码
class Solution {
    private TreeNode pre = null; // 用来记录前一个节点
    
    public boolean isValidBST(TreeNode root) {
        if (root == null) return true;
        
        boolean left = isValidBST(root.left);
        
        if (pre != null && pre.val >= root.val) return false;
        pre = root; // 记录前一个节点
        
        boolean right = isValidBST(root.right);
        
        return left && right;
    }
}
相关推荐
怡人蝶梦几秒前
Java后端技术栈问题排查实战:Spring Boot启动慢、Redis缓存击穿与Kafka消费堆积
java·jvm·redis·kafka·springboot·prometheus
瓯雅爱分享5 分钟前
MES管理系统:Java+Vue,含源码与文档,实现生产过程实时监控、调度与优化,提升制造企业效能
java·mysql·vue·软件工程·源代码管理
PixelMind33 分钟前
【LUT技术专题】图像自适应3DLUT
图像处理·深度学习·算法·3dlut
鬼多不菜1 小时前
一篇学习CSS的笔记
java·前端·css
深色風信子1 小时前
Eclipse 插件开发 5.3 编辑器 监听输入
java·eclipse·编辑器·编辑器 监听输入·插件 监听输入
Blossom.1181 小时前
人工智能在智能健康监测中的创新应用与未来趋势
java·人工智能·深度学习·机器学习·语音识别
木子.李3471 小时前
数据结构-算法学习C++(入门)
数据库·c++·学习·算法
GIS小天1 小时前
AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月31日第94弹
人工智能·算法·机器学习·彩票
shangjg31 小时前
Kafka 如何保证不重复消费
java·分布式·后端·kafka