【算法与数据结构】669、LeetCode修剪二叉搜索树

2023-11-03

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解

一、题目

在这里插入图片描述
在这里插入图片描述

二、解法

  思路分析450、LeetCode删除二叉搜索树中的节点两道题的思路几乎是一样的,只不过终止条件和单层递归逻辑的顺序需要调换,因为本题需要删除的可能不止一个节点,需要先递归到最深处(只要节点非空),然后进行判断,否则在根节点为[low, high]区间外时它把根节点一删除就没有后续操作了,但此时树里面可能还有区间外的节点,造成漏删。删除类型一共有5种,450题已经分析过了。
  程序如下

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if (root == NULL) return root;  // 没找到节点
        root->left = trimBST(root->left, low, high);
        root->right = trimBST(root->right, low, high);

        if (root->val < low || root->val > high) {         // 找到节点
            if (root->right == NULL && root->left == NULL) {    // 左右孩子均为空,返回空节点
                return NULL;
            }
            else if (root->left == NULL) {  // 左孩子为空,右孩子不为空,返回右孩子
                auto retNode = root->right;
                return retNode;
            }
            else if (root->right == NULL) { // 右孩子为空,左孩子不为空,返回左孩子
                auto retNode = root->left;
                return retNode;
            }
            else {  // 左右孩子均不为空,左孩子补位到右孩子最底层最左边的节点上  
                TreeNode* cur = root->right;
                while (cur->left != NULL) {
                    cur = cur->left;
                }
                cur->left = root->left;
                auto retNode = root->right;
                return retNode;
            }
        }
        return root;
    }
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n),需要遍历每一个元素。
  • 空间复杂度: O ( n ) O(n) O(n),最坏情况下,递归深度为n。

三、完整代码

# include <iostream>
# include <vector>
# include <string>
# include <queue>
using namespace std;

// 树节点定义
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if (root == NULL) return root;  // 没找到节点
        root->left = trimBST(root->left, low, high);
        root->right = trimBST(root->right, low, high);

        if (root->val < low || root->val > high) {         // 找到节点
            if (root->right == NULL && root->left == NULL) {    // 左右孩子均为空,返回空节点
                return NULL;
            }
            else if (root->left == NULL) {  // 左孩子为空,右孩子不为空,返回右孩子
                auto retNode = root->right;
                return retNode;
            }
            else if (root->right == NULL) { // 右孩子为空,左孩子不为空,返回左孩子
                auto retNode = root->left;
                return retNode;
            }
            else {  // 左右孩子均不为空,左孩子补位到右孩子最底层最左边的节点上  
                TreeNode* cur = root->right;
                while (cur->left != NULL) {
                    cur = cur->left;
                }
                cur->left = root->left;
                auto retNode = root->right;
                return retNode;
            }
        }
        return root;
    }
};

// 前序遍历迭代法创建二叉树,每次迭代将容器首元素弹出(弹出代码还可以再优化)
void Tree_Generator(vector<string>& t, TreeNode*& node) {
    if (!t.size() || t[0] == "NULL") return;    // 退出条件
    else {
        node = new TreeNode(stoi(t[0].c_str()));    // 中
        if (t.size()) {
            t.assign(t.begin() + 1, t.end());
            Tree_Generator(t, node->left);              // 左
        }
        if (t.size()) {
            t.assign(t.begin() + 1, t.end());
            Tree_Generator(t, node->right);             // 右
        }
    }
}

template<typename T>
void my_print(T& v, const string msg)
{
    cout << msg << endl;
    for (class T::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << ' ';
    }
    cout << endl;
}

template<class T1, class T2>
void my_print2(T1& v, const string str) {
    cout << str << endl;
    for (class T1::iterator vit = v.begin(); vit < v.end(); ++vit) {
        for (class T2::iterator it = (*vit).begin(); it < (*vit).end(); ++it) {
            cout << *it << ' ';
        }
        cout << endl;
    }
}

// 层序遍历
vector<vector<int>> levelOrder(TreeNode* root) {
    queue<TreeNode*> que;
    if (root != NULL) que.push(root);
    vector<vector<int>> result;
    while (!que.empty()) {
        int size = que.size();  // size必须固定, que.size()是不断变化的
        vector<int> vec;
        for (int i = 0; i < size; ++i) {
            TreeNode* node = que.front();
            que.pop();
            vec.push_back(node->val);
            if (node->left) que.push(node->left);
            if (node->right) que.push(node->right);
        }
        result.push_back(vec);
    }
    return result;
}

int main()
{
    // 构建二叉树
    //vector<string> t = { "3", "0", "NULL", "2", "1", "NULL", "NULL", "NULL", "4", "NULL", "NULL" };   // 前序遍历
    //vector<string> t = { "1", "NULL", "2", "NULL", "NULL"};   // 前序遍历
    vector<string> t = { "2", "1", "NULL", "NULL", "3", "NULL", "NULL" };   // 前序遍历
    my_print(t, "目标树");
    TreeNode* root = new TreeNode();
    Tree_Generator(t, root);
    vector<vector<int>> tree = levelOrder(root);
    my_print2<vector<vector<int>>, vector<int>>(tree, "目标树:");

    // 删除目标值
    int low = 3;
    int high = 4;
    Solution s;
    TreeNode* result = s.trimBST(root, low, high);
    vector<vector<int>> tree1 = levelOrder(result);
    my_print2<vector<vector<int>>, vector<int>>(tree1, "结果树:");

    system("pause");
    return 0;
}

end

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【算法与数据结构】669、LeetCode修剪二叉搜索树 的相关文章

  • 攻防世界The_Maya_Society

    The Maya Society 这道题目有三个附件 一个素材 一个html网页 还有一个ELF文件 这里刚开始猜测为html网页逆向 但是网页逆向一般是要给一个js文件 该附件中是没有js文件的 所以应该不是网页逆向 那么猜测应该是附件中

随机推荐

  • vite vue3项目打包部署空白页面问题的处理

    问题 vite vue3项目打包部署上线后 发现是空白页面问题的处理 解决方法 1 在我们vite config js文件中检查是否有路径的指向 2 查看我们的路由模式 将路由模式修改为createWebHashHistory 总结 vit
  • 线上Elastcisearch遇到的问题 org.elasticsearch.transport.ReceiveTimeoutTransportException

    记录 本着使用ES能够快速方便的获取数据 线下搜索模块使用了ES 结果一直报错 org elasticsearch transport ReceiveTimeoutTransportException 10 2 2 121 9200 clu
  • 需求管理

    需求管理 Requirement management 是完整管理模式中的一环 同其他特性诸如完整性 一致性等不可分割 彼此相关而成一体 一套需求管理应当是已知系统需求的完整体现 每部分解决方案都是对总体需求一定比例的满足 甚至是充分满足
  • Redis——Redis介绍

    一 概述 Redis Remote Dictionary Server 即远程字典服务器 是开源免费的 用C语言编写的 高性能的 key value 分布式内存数据库 是一个遵守BSD协议 基于内存运行并支持持久化的NoSQL数据库 是当前
  • Ubuntu18.04安装PCL保姆级教程

    系统环境 Ubuntu18 04 6 LTS 1 安装依赖包 sudo apt get update sudo apt get install git build essential linux libc dev sudo apt get
  • 【Unity小帮手】VuforiaAR解决虚拟按键IVirtuaButtonEventHandler停用问题

    在最新的版本中 已经停用了IVirtuaButtonEventHandler 并且ReisterEventHandler this 使用方法发生了改变 1 修改后主要取消了继承IVirtuaButtonEventHandler类 2 修改R
  • fatal: You are not currently on a branch.To push the history leading to the current (detached HEAD)

    这个错误消息表示你当前处于 detached HEAD 状态 意味着你没有在任何分支上 这可能是由于你使用了git checkout命令切换到了一个特定的提交记录 而不是一个分支 要解决这个问题 你需要创建一个新的分支并将其推送到远程仓库
  • Mysql等保2.0测评

    Mysql等保2 0测评 后续会根据工作中的具体项目要求进行修改 一 身份鉴别 a 应对登录的用户进行身份标识和鉴别 身份标识具有唯一性 身份鉴别信息具有复杂度要求并定期更换 1 登录mysql查看是否使用了口令和密码的组合鉴别身份 mys
  • smop Matlab转成Python

    最近老板有一堆 m文件要我转成python文件 因为我们实验室不是每个人都装了matlab 但是这么多文件 自己写得猴年马月去 秉承能用程序就绝不动手的原则 我去GitHub上找到了smop小工具 这个是GitHub的链接 简述一下安装过程
  • 六、二手房数据分析

    六 二手房数据分析 6 1 背景介绍 6 1 1 实验背景 随着房地产市场发展 房价越来越高 为了的到影响房价的增长因素 现在从数据角度出发 分析以下左右房价的因素 数据介绍 CATE 城区 bedrooms 卧室数量 halls 客厅 A
  • c语言嵌入式web服务器,用C语言实现的简单Web服务器(Linux

    file http session c include include include include include include include include include include include include http
  • IT伦理与道德

    1 个人隐私问题 个人隐私包括传统的个人隐私和现代个人数据 传统的个人隐私有姓名 出生年月 身份证编号 婚姻家庭 教育等 现代个人数据有用户名和密码 IP地址等 合理合法的隐私应受到保护 在计算机时代 隐私极易受到侵害 这最直接的影响就是公
  • LVS负载均衡服务器搭建

    LVS简介 现在LVS已经是Linux标准内核的一部分 在Linux2 4内核以前 使用LVS时必须重新编译内核以支持LVS功能模块 但是从Linux2 4内核心之后 已经完全内置了LVS的各个功能模块 无需给内核打任何补丁 可以直接使用L
  • 异步复位信号的 recovery和removal

    简而言之 DFF的复位置位信号不要在clk的跳变沿附近变化 而是要远离clk沿 一般逻辑对此时序不用关心 比如很多模块的操作流程是复位完了 才开启模块时钟 再启动模块工作 这种流程可以保证不会出现recovery和removal的问题 因为
  • IO流总结

    1 什么是IO I Input O Output 通过IO可以完成硬盘文件的读和写 Java中所有的流都在java io 下 2 IO流的分类 有多种分类方式 输入流 输出流 字节流 字符流 1 一种方式是按照流的方向进行分类 以内存作为参
  • 【C++】空间配置器

    目录 一 空间配置器概念 二 为什么需要空间配置器 三 SGI STL空间配置器实现原理 3 1 一级空间配置器 3 2 二级空间配置器 3 2 1 内存池 3 2 2 SGI STL中二级空间配置器设计 3 2 3 SGI STL二级空间
  • spyder的使用(python编辑器)

    spyder是Anaconda种自带的一种python编辑器 这个编辑器里面保存的是py文件 spyder 创建工程 运行 1 运行整个脚本文件 2 运行当前代码块 3 运行当前代码块 并跳至下一个 4 运行当前命令行 或选中的命令行 5
  • 通过Function Score Query优化Elasticsearch搜索结果

    在使用Elasticsearch进行全文搜索时 搜索结果默认会以文档的相关度进行排序 如果想要改变默认的排序规则 也可以通过sort指定一个或多个排序字段 但是使用sort排序过于绝对 它会直接忽略掉文档本身的相关度 根本不会去计算 在很多
  • 面试笔记(六)---Js实现eventHandler

    js事件的监听器的使用 1 当同一个对象使用 onclick的写法触发多个方法的时候 后一个方法会把前一个方法覆盖掉 也就是说 在对象的onclick事件发生时 只会执行最后绑定的方法 而用事件监听则不会有覆盖的现象 每个绑定的事件都会被执
  • 【算法与数据结构】669、LeetCode修剪二叉搜索树

    文章目录 一 题目 二 解法 三 完整代码 所有的LeetCode题解索引 可以看这篇文章 算法和数据结构 LeetCode题解 一 题目 二 解法 思路分析 450 LeetCode删除二叉搜索树中的节点两道题的思路几乎是一样的 只不过终