数据结构与算法——Java实现 54.力扣1008题——前序遍历构造二叉搜索树

news/2024/11/5 23:57:04 标签: leetcode, 算法, 职场和发展

1008. 前序遍历构造二叉搜索树

给定一个整数数组,它表示BST(即 二叉搜索树 )的 序遍历 ,构造树并返回其根。

保证 对于给定的测试用例,总是有可能找到具有给定需求的二叉搜索树。

二叉搜索树 是一棵二叉树,其中每个节点, Node.left 的任何后代的值 严格小于 Node.val , Node.right 的任何后代的值 严格大于 Node.val

二叉树的 前序遍历 首先显示节点的值,然后遍历Node.left,最后遍历Node.right

示例 1:

输入:preorder = [8,5,1,7,10,12]
输出:[8,5,10,1,7,null,12]

示例 2:

输入: preorder = [1,3]
输出: [1,null,3]

提示:

  • 1 <= preorder.length <= 100
  • 1 <= preorder[i] <= 10^8
  • preorder 中的值 互不相同

方法1 遍历插入法

题目中输入的(先)前序遍历序列表示:根 - 左 - 右 进行遍历,输入后应输出构建好的二叉搜索树节点的层序遍历序列,按照前序遍历的结果进行逐个插入

先序遍历数组构建了一个二叉搜索树。bstFromPreorder 方法负责初始化根节点并遍历数组,insert 方法负责将每个元素插入合适的位置

/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    public TreeNode bstFromPreorder(int[] preorder){
        // preorder 前序遍历结果
        TreeNode root = new TreeNode(preorder[0]);
        for (int i = 1; i < preorder.length; i++) {
            int val = preorder[i];
            insert(root,val);
        }
        return root;
    }

    private TreeNode insert(TreeNode node, int val) {
        if (node == null){
            return new TreeNode(val);
        }
        if (val < node.val){
            node.left = insert(node.left,val);
        } else if (val > node.val) {
            node.right = insert(node.right,val);
        }
        return node;
    }
}


方法2 上限法

1.遍历前序遍历结果数组中每一个值,根据值创建节点,以当前节点作为左右子树的上下限,进行插入判断,分别对各个孩子及上层节点进行判断,然后将各个子树创建完成,最后合并成一个整树

每个节点若成功创建都有:左孩子上限,右孩子上限

2.处理下一个值时,如果超过此上限,那么

        ① 将 null 作为上个节点的孩子

        ② 不能创建节点对象

        ③ 直到不超过上限为止

3.重复 1.2. 两步

解题过程

  • 初始化:定义一个全局索引变量i,用于跟踪当前处理的前序数组中的位置。
  • 主函数:调用insert方法,初始最大值设为Integer.MAX_VALUE。
  • 递归插入:
  • 检查当前索引是否超出数组长度,如果是则返回null。
  • 获取当前索引处的值val。
  • 如果val大于当前允许的最大值max,则返回null(因为这违反了二叉搜索树的性质)。
  • 创建新节点,并递归地构建其左子树(左子树的所有节点值都必须小于当前节点值),然后构建右子树(右子树的所有节点值都必须小于max但可以大于当前节点值)。
  • 返回根节点:最终返回构建好的二叉搜索树的根节点。
/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    int i = 0;
    public TreeNode bstFromPreorder(int[] preorder) {
        return insert(preorder,Integer.MAX_VALUE);
    }
    private TreeNode insert(int[] preorder ,int max){
        if(i == preorder.length){
            return null;
        }
        int val = preorder[i];
        if(val > max){
            return null;
        }
        TreeNode node = new TreeNode(val);
        i++;
        node.left = insert(preorder,val);
        node.right = insert(preorder,max);
        return node;
    }
}

 


方法3 分治法递归

根据前序遍历中的结果确定根节点,小于根节点的为左子树,大于根节点的为右子树,将左子树和右子树分别递归代入以上判断步骤中,直至判断完所有元素

分而治之思想

前序遍历的第 1 个结点一定是二叉树的根结点;
由于构造出来的是 BST,第 1 个结点后面被分成了两个子区间:
第 1 个子区间里所有的元素都严格小于根结点 -> 递归构建成根结点的左子树;
第 2 个子区间里所有的元素都严格大于根结点 -> 递归构建成根结点的右子树。


/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

public class Solution {

    public TreeNode bstFromPreorder(int[] preorder) {
        int len = preorder.length;
        if (len == 0) {
            return null;
        }

        return buildBST(preorder, 0, len - 1);
    }

    /**
     * 使用 preorder 的子区间 [left, right] 构建二叉树
     *
     * @param preorder
     * @param left
     * @param right
     * @return
     */
    private TreeNode buildBST(int[] preorder, int left, int right) {
        if (left > right) {
            return null;
        }

        TreeNode root = new TreeNode(preorder[left]);
        if (left == right) {
            return root;
        }

        int i = left;
        while (i + 1 <= right && preorder[i + 1] < preorder[left]) {
            i++;
        }

        // 此时子区间 [left + 1..i] 所有元素都 < preorder[left]
        //  [i + 1..right] 所有元素都 > preorder[left]

        TreeNode leftTree = buildBST(preorder, left + 1, i);
        TreeNode rightTree = buildBST(preorder, i + 1, right);

        root.left = leftTree;
        root.right = rightTree;
        return root;
    }
}


http://www.niftyadmin.cn/n/5739954.html

相关文章

Pycharm配置anaconda的解释器教程

因为自己配置过程中遇到了一些问题&#xff0c;所以写一条记录一下 首先打开pycharm软件&#xff0c;点击文件→设置 进入设置界面&#xff0c;找到解释器&#xff0c;然后添加本地解释器 选择conda环境&#xff0c;首次加载环境时&#xff0c;系统可能会显示无可执行文件 不用…

【C++篇】在秩序与混沌的交响乐中: STL之map容器的哲学探寻

文章目录 C map 容器详解&#xff1a;高效存储与快速查找前言第一章&#xff1a;C map 的概念1.1 map 的定义1.2 map 的特点 第二章&#xff1a;map 的构造方法2.1 常见构造函数2.1.1 示例&#xff1a;不同构造方法 2.2 相关文档 第三章&#xff1a;map 的常用操作3.1 插入操作…

如何在BSV区块链上实现可验证AI

​​发表时间&#xff1a;2024年10月2日 nChain的顶尖专家们已经找到并成功测试了一种方法&#xff1a;通过区块链技术来验证AI&#xff08;人工智能&#xff09;系统的输出结果。这种方法可以确保AI模型既按照规范运行&#xff0c;避免严重错误&#xff0c;遵守诸如公平、透明…

在大型应用程序中共存 Vue 2 和 Vue 3

工作原理 为了说明我们的混合应用程序的架构以及 Vue 2 和 Vue 3 之间的交互&#xff0c;我们有两张图&#xff1a;一张代表整体流程&#xff0c;另一张展示模块关系。 上图展示了应用程序内模块的逐步迁移。它展示了如何使用 Vue 2 或 Vue 3 构建每个模块&#xff0c;从而实现…

AI开发-三方库-torch-torchvision

1 需求 数据集&#xff1a;torchvision.datasets torchvision.datasets.MNIST数据变换&#xff1a;torchvision.transforms torchvision.transforms.Composetorchvision.transforms.ToTensortorchvision.transforms.Normalize模型&#xff1a;torchvision.models可视化工具&…

【网络】自定义协议——序列化和反序列化

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是序列化和分序列&#xff0c;并且自己能手撕网络版的计算器。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不…

SQL server 列转行

在 SQL Server 中&#xff0c;将列转换为行的操作通常被称为“透视”&#xff08;Pivot&#xff09;的逆操作&#xff0c;即“反透视”&#xff08;Unpivot&#xff09;。SQL Server 提供了 UNPIVOT 关键字来实现这一功能。假设你有一个表 EmployeeDetails&#xff0c;其中包含…

Unity照片墙效果

Unity照片墙效果&#xff0c;如下效果展示 。 工程源码