热门面试题第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;
    }
}
相关推荐
传奇开心果编程16 分钟前
【springboot基础语法学与练】第 1 课:从零开始
java·spring boot·后端·学习
SL_staff18 分钟前
财务系统慎用低代码?从数据模型闭环看合规落地的技术实践
java·低代码·全栈
叠层归一研究院23 分钟前
基于极限自指的叠层归一宇宙结构理论——无元外部封闭系统的内生区分模型
人工智能·经验分享·算法·agi
滕州市燕猫虎计算机科技工作室个体工商户27 分钟前
IDEA:Command line is too long
java·ide·intellij-idea
步行cgn1 小时前
Spring p 命名空间注入详解
java·前端·spring
YatHinLay1 小时前
MyBatis 流式查询实战:ResultHandler 处理海量数据
java
天天被压力1 小时前
【跨市场数据实战 #08】可转债折价机会怎么筛:3个接口抓比价、列表和实时盘口
java·人工智能·python
Selvaggia1 小时前
Diffusion Model 的基本原理与模型架构
算法
张某布响丸辣2 小时前
附件下载的安全边界:路径白名单、NAS 哨兵文件与 Redis Lua 一次性令牌
java·redis·redis lua·nas哨兵
YatHinLay3 小时前
Spring Boot + Calcite 实现跨库查询
java