Day23~669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

79 阅读5分钟

摘要

本文介绍LeetCode中的三道二叉树题目:669.修剪二叉搜索树、108.将有序数组转为二叉搜索树、538.把二叉搜索树转为累加树。最后,由ChatGPT总结了二叉树问题的关键解题技巧。

1、669. 修剪二叉搜索树

1.1 思路

  • 递归遍历,利用二叉搜索树是有序的
  • 如果要删除的元素小于low,返回修剪后的右子树;如果要删除的元素大于high,返回修剪后的左子树
  • 递归地对其左子树和右子树进行修剪

ChatGPT的思路

  1. 对于BST,其左子树中的所有节点值都小于根节点的值,而右子树中的所有节点值都大于根节点的值。
  2. 因此,如果当前节点的值小于low,那么它以及其左子树的所有节点都应该被修剪,因为它们都小于low
  3. 同样,如果当前节点的值大于high,那么它以及其右子树的所有节点都应该被修剪,因为它们都大于high
  4. 如果当前节点的值在[low, high]的范围内,那么我们保留该节点,然后递归地对其左子树和右子树进行修剪。

1.2 代码

    public TreeNode trimBST(TreeNode root, int low, int high) {
        if(root == null) {
            return null;
        }
        if(root.val < low) {
            return trimBST(root.right, low, high);
        }
        if(root.val > high) {
            return trimBST(root.left, low, high);
        }
​
        root.left = trimBST(root.left, low, high);
        root.right = trimBST(root.right, low, high);
        return root;
    }

2、108.将有序数组转换为二叉搜索树

2.1 思路

  • 递归遍历,定义start, end分别为开始下标和结束下标
  • 递归终止:start<end返回空,start==end返回new TreeNode(nums[start])
  • 递归过程:定义mid=(start+end)/2,左子树等于[start, mid-1],右子树等于[mid+1, end]

ChatGPT的思路

  1. 对于BST,它的中序遍历是一个升序排列的数组。因此,如果我们想要构建一个高度平衡的BST,可以选择中间元素作为根节点,然后将左侧的部分数组构建成左子树,右侧的部分数组构建成右子树。
  2. 为了确保树的高度平衡,我们需要不断地选择中间元素作为根节点,并递归构建左右子树,直到所有的元素都被使用。
  3. 递归函数的输入参数可以包括数组的起始索引和结束索引,表示当前子数组的范围。递归的终止条件是起始索引大于结束索引,此时返回null表示空树。
  4. 在每一次递归调用中,我们计算中间元素的索引,选择它作为当前子树的根节点,并将左侧部分数组和右侧部分数组传递给递归函数,分别构建左子树和右子树。
  5. 最后,将当前根节点返回,构建完成的BST就是由递归函数返回的根节点及其子树构成的。

2.2 代码

    public TreeNode sortedArrayToBST(int[] nums) {
        return doSortedArrayToBST(nums, 0, nums.length-1);
    }
​
    public TreeNode doSortedArrayToBST(int[] nums, int start, int end) {
        if(start > end) {
            return null;
        }
        if(start == end) {
            return new TreeNode(nums[start]);
        }
​
        int mid = (start + end) / 2;
        TreeNode node = new TreeNode(nums[mid]);
        node.left = doSortedArrayToBST(nums, start, mid-1);
        node.right = doSortedArrayToBST(nums, mid+1, end);
        return node;
    }

3、538.把二叉搜索树转换为累加树

3.1 思路

  • 同501.二叉搜索树中的众数,中序遍历为左右中,因为需要从大到小遍历, 所以遍历顺序是右中左
  • 递归终止:当前节点为null
  • 递归过程:定义prev为前一个节点,设置root节点的值为当前值+前一个节点的值,然后重新设置prev=root

3.2 代码

    public TreeNode convertBST(TreeNode root) {
        doConvertBST(root); 
        return root;
    }
​
    public void doConvertBST(TreeNode root) {
        if(root == null) {
            return;
        }
​
        doConvertBST(root.right);
​
        root.val = root.val + prev.val;
        prev = root;
        
        doConvertBST(root.left);
    }

4、总结

这篇总结提供了对「代码随想录」中关于二叉树的文章的分类和摘要,以及每个问题的递归和迭代解决方案。以下是主要内容的概要:

  1. 二叉树的理论基础:介绍了二叉树的基本概念,包括种类、存储方式、遍历方式和定义方式。
  2. 二叉树的遍历方式:详细讨论了深度优先遍历和广度优先遍历的递归和迭代方法。
  3. 求二叉树的属性:解释了如何计算二叉树的最大深度、最小深度、节点数量、是否平衡、路径总和等属性,并提供了递归和迭代的解决方案。
  4. 二叉树的修改与构造:包括翻转二叉树、构造二叉树、构造最大的二叉树、合并两个二叉树等问题的递归和迭代方法。
  5. 求二叉搜索树的属性:涵盖了二叉搜索树中的搜索、判断是否为二叉搜索树、找最小绝对差、求众数、二叉搜索树转累加树等问题的解决方案。
  6. 二叉树的公共祖先问题:解释了在二叉树中找到两个节点的最近公共祖先的递归和迭代方法。
  7. 二叉搜索树的修改与构造:包括在二叉搜索树中插入节点、删除节点、修剪树、构造二叉搜索树等问题的解决方案。

总之,这篇总结提供了对二叉树相关问题的系统分类和解决方法,有助于学习和复习与二叉树相关的算法和数据结构知识。

1、二叉树题目选择什么遍历顺序?

涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。

求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。

求二叉搜索树的属性,一定是中序了,要不白瞎了有序性了。

参考资料

代码随想录-二叉搜索树的最近公共祖先

代码随想录-二叉搜索树中的插入操作

代码随想录-删除二叉搜索树中的节点