代码随想录算法训练营之JAVA|第二十天| 669. 修剪二叉搜索树

今天是第20天刷leetcode,立个flag,打卡60天,如果做不到,完成一件评论区点赞最高的挑战。

算法挑战链接

力扣icon-default.png?t=N6B9https://leetcode.cn/problems/trim-a-binary-search-tree/description/

第一想法

题目理解:将二叉搜索树中不再区间内的节点去除掉。

首先我先模拟一下完成这个的操作。

1. 判断当前节点是否在区间内,如果在则继续判断他的左右孩子是否在区间内

2. 如果当前节点不在区间内,分为两种情况:

        2.1 如果当前节点小于区间最小值,则往当前节点的右节点寻找下一个节点

        2.2 如果当前节点大于区间最大值,则往当前节点的左节点寻找下一个节点

这种操作和递归的操作很相似,所以我第一选择是选用递归的方式来做

代码如下:

 /**
     * 使用递归的方法来实现
     * 递归三要素
     * 入参和返回值:入参->当前节点,返回值->可以被当作树的节点
     * 结束条件:当前节点为null
     * 当前递归做的事情:确定当前节点是否可以作为返回值,
     *                  如果当前节点小于区间的左边,则往右边递归,
     *                  如果当前节点大于区间的右边,则往左边递归。
     * @param root
     * @param low
     * @param high
     * @return
     */
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if (root == null) {
            return null;
        }
        //确定当前节点是否可以作为返回值
        if (root.val >= low && root.val <= high) {
            root.left = trimBST(root.left, low, high);
            root.right = trimBST(root.right, low, high);
            return root;
        }

        if (root.val < low) {
            return trimBST(root.right, low, high);
        }
        return trimBST(root.left, low, high);

    }

可以递归的操作都是可以迭代来完成的,我想了一下如何使用迭代来完成,但是没有想出来。于是看代码随想录去找找答案。

看完代码随想录之后的想法 

代码随想录记录了迭代法来完成的过程。大致是这样的:

先找到头节点,然后修剪左树枝,最后修剪右树枝。

class Solution {
    //iteration
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if(root == null)
            return null;
        while(root != null && (root.val < low || root.val > high)){
            if(root.val < low)
                root = root.right;
            else
                root = root.left;
        }

        TreeNode curr = root;
        
        //deal with root's left sub-tree, and deal with the value smaller than low.
        while(curr != null){
            while(curr.left != null && curr.left.val < low){
                curr.left = curr.left.right;
            }
            curr = curr.left;
        }
        //go back to root;
        curr = root;

        //deal with root's righg sub-tree, and deal with the value bigger than high.
        while(curr != null){
            while(curr.right != null && curr.right.val > high){
                curr.right = curr.right.left;
            }
            curr = curr.right;
        }
        return root;
    }
}

 可以发现他一共找来三次,先找头节点,找处于区间的最小值,找处于区间的最大值。寻找的方式都是一样的:使用二叉搜索树的特性,左边节点 < 中间节点 < 右边节点

实现过程中遇到哪些困难 

迭代法没有想出来~主要的原因是没有想到需要先找头节点,然后在修剪左右两边,只想着如果修剪了。

今日收获

要确定一棵树,得先确定他的根节点,如果不确定那是不能确定这棵树的。

你可能感兴趣的:(算法)