LeetCode刷题day23|669修剪二叉搜索树、108将有序数组转换为二叉搜索树、538把二叉搜索树转换为累加树

文章目录

  • 一、669修剪二叉搜索树
  • 二、108将有序数组转换为二叉搜索树
  • 三、538把二叉搜索树转换为累加树

一、669修剪二叉搜索树

由于昨天做过在二叉树中删除某个节点,做这道题其实有思路,不是很难。并且我个人认为他比删除某个节点要简单,因为它不需要考虑删除某个节点后左右子树都还存在的情况——在该题中,删除一个节点后,至少会连带着删除他的某一个孩子节点

以下是代码部分:

public class 修剪二叉搜索树669 {

    //当作删除多个节点
    public TreeNode trimBST(TreeNode root, int low, int high) {

        if(root == null)
            return null;

        //当前节点小于low,则左孩子都小于low
        if(root.val < low){
            // 两种情况:有右孩子或者没有
            // 没有右孩子直接可以return null
            if(root.right != null)
                return trimBST(root.right, low, high);
            else
                return null;
        }
        else if(root.val > high){
            if(root.left != null)
                return trimBST(root.left, low, high);
            else
                return null;
        }

        root.left = trimBST(root.left, low, high);
        root.right = trimBST(root.right, low, high);

        return root;
    }
}

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

这道题刚开始还是卡了挺长时间,最主要的原因是忘记怎么实现二叉树的构造了。在看了之前如何构造二叉树后,这道题还是比较容易解决的。
主要的笔记:

  1. 构造二叉树的思路:选取一个中间的节点,将这个数组分为左区间和右区间。递归去便利左区间,构成了左子树;递归去遍历右区间,构成了右子树。
  2. 注意区间的选取,是左闭右开、还是左闭右闭。

以下是代码部分:

public class 将有序数组转换为二叉搜索树108 {

    //这道题刚开始卡壳了。因为忘记怎么构造二叉树了。
    //了解如何构造二叉树,这道题还是比较容易想到的。
    public TreeNode sortedArrayToBST(int[] nums) {

        return preorder(nums, 0, nums.length);
    }

    private TreeNode preorder(int[] nums, int left, int right){

        //边界条件,数组为空。数组左闭右开
        if(left == right)
            return null;

        //挑选最中间的点作为当前节点
        int mid =(left + right) / 2;
        TreeNode node = new TreeNode(nums[mid]);
        node.left = preorder(nums, left, mid);
        node.right = preorder(nums, mid+1, right);

        return node;
    }

    //构造二叉树的思路:选取一个中间的节点,将这个数组分为左区间和右区间。递归去便利左区间,构成了左子树;递归去遍历右区间,构成了右子树。
}

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

这道题的自己的思路:遍历两遍二叉树,第一遍求出总和。第二遍通过中序遍历再一个一个地减去总和。(虽然知道肯定有遍历一次的方法,但是实在想不到。)

以下是代码部分:

int sum = 0;
    //思路:遍历两遍二叉树,第一遍求出总和。第二遍通过中序遍历再一个一个地减去总和
    public TreeNode convertBST(TreeNode root) {

        preorder(root);
        inorder(root);
        return root;
    }

    private void preorder(TreeNode node){
        if(node == null)
            return;

        sum+=node.val;
        preorder(node.left);
        preorder(node.right);
    }

    private void inorder(TreeNode node){
        if(node == null)
            return;

        inorder(node.left);

        //这里要额外定义一个变量tmp,因为要先存储sum-原val的值是多少
        int tmp = sum - node.val;
        node.val = sum;
        sum = tmp;

        inorder(node.right);
    }

在看了题解之后,直接惊呼还可以这样——先遍历右孩子,再遍历左孩子。这说明自己还是没有彻底掌握二叉树的思想。
当然,有一处踩坑的地方,就是num必须定义为全局变量,否则遇到空节点就会丢失之前的值。

以下是代码部分:

//踩坑
    //num必须定义为全局变量。因为遇到空节点会丢失num的值
    int num = 0;
    public TreeNode convertBST1(TreeNode root) {

        inorder2(root);
        return root;
    }

    private void inorder2(TreeNode node){

        if(node == null)
            return;

        inorder2(node.right);
        node.val+=num;
        num = node.val;
        inorder2(node.left);
    }

你可能感兴趣的:(leetcode,算法,数据结构)