代码随想录Day23 | ● 669. 修剪二叉搜索树 ● 669. 修剪二叉搜索树 ● 669. 修剪二叉搜索树

代码随想录Day23 | ● 669. 修剪二叉搜索树 ● 669. 修剪二叉搜索树 ● 669. 修剪二叉搜索树

  • 修剪二叉搜索树
  • 将有序数组转换为二叉搜索树
  • 把二叉搜索树转换为累加树
  • 使用哪种遍历顺序

修剪二叉搜索树

文档讲解:代码随想录
视频讲解: 你修剪的方式不对,我来给你纠正一下!| LeetCode:669. 修剪二叉搜索树
状态

主要考虑的情况是当删除节点时,如果当前节点的值小于low,那么说明左子树所有节点都是小于Low的,而对于右子树需要一直递归直到当前节点的值大于等于val。而对于大于high的节点,就说明右子树所有节点都是大于high的,而对于左子树需要一直递归直到当前节点的值小于等于val。

  1. 当当前节点为空,就返回
  2. 单层递归
//对中节点的情况处理,如果不满足就需要更新
if(root->val < low)
{
	//向右子树寻找第一个大于等于low的节点
	TreeNode* left = find(root->right,low,high);
	return left;
}
if(root->val > high)
{
	//向左子树寻找第一个小于等于High的节点
	TreeNode* right = find(root->left,low,high);
	return right;
}

//正确中节点的左子树
root->left = find(root->left,low,high);
//正确中节点的右子树
root->right = find(root->right,low,high);

具体代码

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if(root == nullptr) return root;

        //中节点
        if(root->val < low)
        {
            TreeNode* left = trimBST(root->right,low,high);
            return left;
        }
        if(root->val > high)
        {
            TreeNode* right = trimBST(root->left,low,high);
            return right;
        }

        //向下节点递归
        root->left = trimBST(root->left,low,high);
        root->right = trimBST(root->right,low,high);

        return root;
    }
};

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

文档讲解:代码随想录
视频讲解: 构造平衡二叉搜索树!| LeetCode:108.将有序数组转换为二叉搜索树
状态

本题和构造二叉树的方法类似,在数组中找到根节点位置,然后以根节点分隔数组,递归调用函数,并使用根节点的左指针和右指针接受返回值。
由于已经是升序数组了,所以以数组的mid位置的数为根节点,左边的构成左子树,右边的构成右子树。左右两个数组同样升序,那么可以递归这样建树,递归函数每次传入数组的左右边界,并用上一个节点的左和右值接受子数组的返回节点。
当左边界大于等于右边界时,就返回空节点。

class Solution {
public:
    TreeNode* getArray(vector& nums, int left, int right)
    {
        if(left > right) return nullptr;
        int mid = left +(right-left)/2;
        TreeNode* root = new TreeNode(nums[mid]);
        root->left = getArray(nums,left,mid-1);
        root->right = getArray(nums,mid+1,right);
        return root;
    }
public:
    TreeNode* sortedArrayToBST(vector& nums) {
        int left = 0;
        int right = nums.size()-1;
        return getArray(nums, left ,right);
    }
};

把二叉搜索树转换为累加树

文档讲解:代码随想录
视频讲解: 普大喜奔!二叉树章节已全部更完啦!| LeetCode:538.把二叉搜索树转换为累加树
状态

二叉搜索树,大于等于相当于该节点的值等于右边所有节点值,显然中序遍历,节点值就是从节点开始向右的所有值。
所以如果先递归到最右的节点,进行一个右中左方式的遍历,我们定义一个全局变量,用来记录当前已经遍历的节点的和,那么下一个遍历的节点之和就是这个和加上其本身

class Solution {
private:
    int sum = 0;
public:
    TreeNode* convertBST(TreeNode* root) {
        if(root == nullptr) return nullptr;
        convertBST(root->right);
        sum += root->val;
        root->val = sum;
        convertBST(root->left);
        return root;
    }
};

使用哪种遍历顺序

中节点的位置一般为处理结果的位置,左右节点一般只用来递归调用

  1. 对于二叉树的构造,那么一般使用前序,通过寻找中节点在数组的位置,然后分割数组,递归。要注意区间闭合的不变性
TreeNode* get(vector& nums, int left, int right)
{
	//中节点
	root = new mid;
	//
	root->left = get(nums,left,mid-1);
	root->right = get(nums,mid+1,right);
}
  1. 对于二叉搜索树,要考虑中序,因为二叉搜索树是有序的,左子树是小于中节点的,右子树是大于中节点的。利用中序可以很好的划分左右节点的搜寻路径
  2. 对于一些普通二叉树的处理,一般都是用后序,其实就是需要使用递归函数的返回值做计算,但也有例外比如求二叉树的所有路径,由于需要父节点去指向子节点。但使用前序遍历时,需要注意回溯问题。因为每个父节点可能会有两条路径。

还是得多复习复习,刷了这几天感觉头有点昏昏的,还没形成体系。

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