今天是第20天刷leetcode,立个flag,打卡60天,如果做不到,完成一件评论区点赞最高的挑战。
算法挑战链接
力扣https://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;
}
}
可以发现他一共找来三次,先找头节点,找处于区间的最小值,找处于区间的最大值。寻找的方式都是一样的:使用二叉搜索树的特性,左边节点 < 中间节点 < 右边节点
实现过程中遇到哪些困难
迭代法没有想出来~主要的原因是没有想到需要先找头节点,然后在修剪左右两边,只想着如果修剪了。
今日收获
要确定一棵树,得先确定他的根节点,如果不确定那是不能确定这棵树的。