第二十三天| 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

Leetcode 669. 修剪二叉搜索树

题目链接:669 修剪二叉搜索树

题干:给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

思考一:递归法。终止条件:若当前节点为空则返回空。单层递归逻辑:如果当前节点val值大于最大区间值,递归处理其左子树并返回。如果当前节点val值小于最小区间值,递归处理其右子树并返回。如果当前节点val值在区间内,则递归处理左右子树。

代码:

class Solution {
public:TreeNode* trimBST(TreeNode* root, int low, int high) {if (!root)  return nullptr;if (root->val > high)       //当前节点val值大于区间最大值时递归处理其左子树return trimBST(root->left, low, high);if (root->val < low)        //当前节点val值小于区间最小值时递归处理其右子树return trimBST(root->right, low, high);root->left = trimBST(root->left, low ,high);root->right = trimBST(root->right, low ,high);return root;}
};

思考二:迭代法。由于二叉搜索树的节点有序性,遍历过程无需借助栈和队列。先将root移动到区间范围内,再处理其左右子树。

代码:

class Solution {
public:TreeNode* trimBST(TreeNode* root, int low, int high) {if (!root)  return nullptr;//处理头节点 让root移动到区间内while (root && (root->val > high || root->val < low)) {if (root->val > high)   root = root->left;else    root = root->right;}TreeNode* cur = root;       //记录根节点//处理左子树while (cur) {while (cur->left && cur->left->val < low)cur->left = cur->left->right;cur = cur->left;}cur = root;     //当前节点改为根节点//处理右子树while (cur) {while (cur->right && cur->right->val > high)cur->right = cur->right->left;cur = cur->right;}return root;}
};

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

题目链接:108 将有序数组转换为二叉搜索树

题干:给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

  • 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

思考一:递归法。由于要求高度平衡,则每次递归从数组区间中间位置取值作为节点元素,再以此位置分割数组区间,分别处理左右区间作为当前节点的左右子树。

代码:

class Solution {
public:TreeNode* traversal(vector<int>& nums, int left, int right) {if (left >= right)  return nullptr;int middle = (left + right) / 2;TreeNode* root = new TreeNode(nums[middle]);//分割递归处理  左闭右开root->left = traversal(nums, left, middle);root->right = traversal(nums, middle + 1, right);return root;}TreeNode* sortedArrayToBST(vector<int>& nums) {if (nums.size() == 0)  return nullptr;return traversal(nums, 0, nums.size());}
};

思考二:迭代法。通过三个队列来模拟递归传值过程,一个队列放遍历的节点,一个队列放左区间下标,一个队列放右区间下标。

代码:

class Solution {
public:TreeNode* sortedArrayToBST(vector<int>& nums) {if (nums.size() == 0) return nullptr;TreeNode* root = new TreeNode(0);   // 初始根节点queue<TreeNode*> nodeQue;           // 放遍历的节点queue<int> leftQue;                 // 保存左区间下标queue<int> rightQue;                // 保存右区间下标nodeQue.push(root);                 // 根节点入队列leftQue.push(0);                    // 0为左区间下标初始位置rightQue.push(nums.size() - 1);     // nums.size() - 1为右区间下标初始位置while (!nodeQue.empty()) {TreeNode* curNode = nodeQue.front();nodeQue.pop();int left = leftQue.front(); leftQue.pop();int right = rightQue.front(); rightQue.pop();int mid = left + ((right - left) / 2);curNode->val = nums[mid];       // 将mid对应的元素给中间节点if (left <= mid - 1) {          // 处理左区间curNode->left = new TreeNode(0);nodeQue.push(curNode->left);leftQue.push(left);rightQue.push(mid - 1);}if (right >= mid + 1) {         // 处理右区间curNode->right = new TreeNode(0);nodeQue.push(curNode->right);leftQue.push(mid + 1);rightQue.push(right);}}return root;}
};

Leetcode 538.把二叉搜索树转换为累加树

题目链接:538 把二叉搜索树转换为累加树

题干:给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。

思考一:递归法。由于二叉搜索树的节点有序性,任意节点的右子树键值均大于节点键值。故采取右中左的顺序遍历二叉树,遍历过程顺便记录前一个节点键值。

代码:

class Solution {
public:int pre = 0;        //记录前一个结点键值TreeNode* convertBST(TreeNode* root) {if (!root)  return nullptr;root->right = convertBST(root->right);      //右root->val += pre;        //中pre = root->val;        //更新键值root->left = convertBST(root->left);        //左return root;}
};

思考二:迭代法。修改中序遍历的顺序迭代法的节点遍历顺序为右中左,同时修改中节点处理逻辑为修改键值和更新记录(记录前一个结点键值)。

中序遍历迭代法写法:第十四天| 二叉树的递归遍历、二叉树的迭代遍历、二叉树的统一迭代法

代码:

class Solution {
public:TreeNode* convertBST(TreeNode* root) {stack<TreeNode*> st;TreeNode* cur = root;int pre = 0;while (cur || !st.empty()) {if (cur) {st.push(cur);cur = cur ->right;      //右} else {cur = st.top(); st.pop();cur->val += pre;        //中pre = cur->val;cur = cur->left;        //左}}return root;}
};

 二叉树专题总结:

  • 熟悉二叉树的前中后序遍历以及层序遍历。
  • 递归三部曲的练习:
    • 确定递归函数的参数和返回类型
      • 如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值。
      • 如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需要返回值。
      • 如果要搜索其中一条符合条件的路径,那么递归一定需要返回值,因为遇到符合条件的路径了就要及时返回。
    • 确定终止条件
    • 确定单层递归的逻辑
      • 考虑每题不同二叉树的各类情况
      • 明确是否需要遍历整棵二叉树以及左、中、右节点的遍历顺序
  • 迭代方式,采用栈和队列来辅助。其中的统一迭代法采用标记法来确定节点是否访问过。
  • 构造二叉树要坚持区间不变量原则。注意类似用数组构造二叉树的题目,每次分隔尽量不要定义新的数组,而是通过下标索引直接在原数组上操作,这样可以节约时间和空间上的开销。
  • 二叉树题目总结:
    • 涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。

    • 求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。

    • 求二叉搜索树的属性,一定是中序,利用好节点的有序性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/663617.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常见的6种软件测试用例设计方法

常见的软件测试用例设计方法&#xff0c;个人认为主要是下面这6种&#xff1a; 流程图法&#xff08;也叫场景法&#xff09;等价类划分法边界值分析判定表正交法错误推测法 这6种常见方法中&#xff0c;我分别按照定义、应用场景、使用步骤、案例讲解这4个部分进行讲解。 所…

实习|基于SSM的实习管理系统设计与实现(源码+数据库+文档)

实习管理系统目录 目录 基于SSM的实习管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员功能介绍 &#xff08;1&#xff09;管理员登录 &#xff08;2&#xff09;实训方向管理 &#xff08;3&#xff09;公告信息管理 &#xff08;4&#xff0…

C++——STL标准模板库——常用算法归纳

使用标准模板库提供的算法需要包含头文件&#xff1a;algorithm&#xff0c;其中包含了遍历、查找、排序、拷贝和替换等算法。当容器储存内置数据类型可使用STL提供函数对象&#xff0c;当容器储存自定义数据类型时需要自定义数据对象或者函数用于提供自定义数据类型的比较、计…

STM32MP135开发板助力电力行业,IEC61850协议移植笔记

1.概述 IEC61850是变电站自动化系统&#xff08;SAS&#xff09;中通信系统和分散能源&#xff08;DER&#xff09;管理的国际标准。它通过标准的实现&#xff0c;实现了智能变电站的工程运作标准化。使得智能变电站的工程实施变得规范、统一和透明&#xff0c;在电力和储能系…

go语言-用channel控制goroutine的退出

用channel控制goroutine的退出 本文简要介绍了&#xff0c;如何用channel控制goroutine的退出的基本方法 for-range主动停止goruitine package mainimport ("fmt""sync""time" )/* Go并发编程模型&#xff1a;主动停止goroutine 方法一&#…

(java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~

目录 冒泡排序(BubbleSort)&#xff1a; 代码详解&#xff1a; 冒泡排序的优化&#xff1a; 选择排序(SelectSort)&#xff1a; 代码详解&#xff1a; 插入排序&#xff08;InsertSort&#xff09;&#xff1a; 代码详解&#xff1a; 希尔排序(ShellSort)&#xff1a; 法一…

Java中的常用API

常用API Object类浅克隆与深克隆 ObjectsObjects中的equals 包装类StringBuilder和StringBufferStringBuilder是可变字符串对象StringBuffer线程安全案例![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/87649c20e6464113a42aee5f16f1ee22.png) StringJoiner Object…

关于ZYZ旋转和XYZ旋转

ZYZ旋转和XYZ旋转 概述1、XYZ旋转2、ZYZ旋转 概述 以下公式默认为右手坐标系&#xff1b;ZYZ通常可以避免死解情况&#xff0c;因此在六轴末端解算时常被用到&#xff1b;参考文章 1、XYZ旋转 XYZ旋转一般是绕固定轴旋转(外旋)&#xff0c;旋转矩阵的构成为&#xff1a;RzRy…

软考 系统分析师系列知识点之需求管理(3)

接前一篇文章&#xff1a;软考 系统分析师系列知识点之需求管理&#xff08;2&#xff09; 所属章节&#xff1a; 第11章. 软件需求工程 第8节. 需求管理 11.8.4 需求跟踪 根据IEEE的定义&#xff0c;可跟踪性包含两个层面的含义&#xff1a;一个是开发过程的两个或多个产品之…

无广告iOS获取设备UDID 简单方便快捷

ps&#xff1a; 为啥不用蒲公英了&#xff0c;就是因为有广告了&#xff0c;获取个UDID还安装游戏&#xff0c;真恶心?&#xff0c;所以找了新的获取UDID都方法&#xff0c;网页直接获取就可以&#xff0c;不会安装软件。 UDID 是一种 iOS 设备的特殊识别码。除序号之外&…

(1)cpu0简介

一、cpu0介绍 cpu032位架构16位通用寄存器&#xff0c;协处理器和其他特殊寄存器 &#xff08;1&#xff09;通用寄存器 全局指针寄存器&#xff1a;"Global Pointer register"&#xff08;全局指针寄存器&#xff09;是一个在某些处理器架构中存在的专用寄存器&…

单臂路由实验(思科)

一&#xff0c;实验目的 在路由器的一个接口上通过配置子接口的方式&#xff0c;实现相互隔离的不同vlan之间互通。 二&#xff0c;设备配置 Switch1 Switch>enable 全局模式 Switch#configure terminal 配置模式 Switch(config)#vlan 10 …

【leetcode】20. 有效的括号

有效的括号 题目链接 // 栈结构 typedef char valuetype; typedef struct {valuetype* arr;int top;int capacity; } Stack;void Init(Stack* stack);void Push(Stack* stack, valuetype value); void Pop(Stack* stack);valuetype Top(Stack* stack); int Size(Stack* stack…

嵌入式中C 语言中的三块技术难点

C 语言在嵌入式学习中是必备的知识&#xff0c;甚至大部分操作系统都要围绕 C 语言进行&#xff0c;而其中有三块技术难点&#xff0c;几乎是公认级别的“难啃的硬骨头”。 今天就来带你将这三块硬骨头细细拆解开来&#xff0c;一定让你看明白了。 0x01 指针 指针是公认最难理…

26元/月起!腾讯云一键自动搭建4核16G幻兽帕鲁服务器

腾讯云无需任何配置自动搭建幻兽帕鲁游戏联机服务器&#xff0c;游戏24小时在线&#xff0c;4核16G游戏联机服务器低至26元/月起&#xff0c;新手小白也能一键搭建属于自己的幻兽帕鲁游戏联机服务器&#xff01; 第一步&#xff1a;购买游戏联机服务器 购买入口&#xff1a;htt…

Django知识随笔

目录 1.如何再ajax中传输post数据&#xff1f; 2.在form表单中使用jquery序列化&#xff0c;input框过多。 1.如何再ajax中传输post数据&#xff1f; 在ajax传递的那个网址&#xff0c;会调用你路由的视图函数&#xff0c;在视图函数上面加一句 csrf_exempt 。写上之后会有提…

Android:RecyclerView跨行跨列的LayoutManager:Spannedgridlayoutmanager

前言&#xff1a; RecyclerView可以使用GridLayoutManager实现跨行&#xff0c;但是不能跨列&#xff1b;瀑布流布局可以跨列但是又不能跨行。原生自带的各个LayoutManager中并没有可以又跨行又能跨列的。网上搜寻了一番&#xff0c;找到了一个亲测可行好用的三方库&#xff1…

DL/T1578-2021电力线路多旋翼无人机巡检系

DL/T1578-2021电力线路多旋翼无人机巡检系 DL/T 1578—2021标准的发布和实施对于架空电力线路的巡检工作具有里程碑式的意义。它不仅填补了多旋翼无人机巡检系统在行业标准方面的空白&#xff0c;还为电力行业提供了一套完整、科学的测试和评估方法。这将有助于提高架空电力线…

大小相等的numpy数组运算及数组与标量的运算

1 大小相等的numpy数组运算及数组与标量的运算 不用编写循环即可对numpy数组执行批量运算&#xff0c;而用数组表达式代替循环的做法&#xff0c;称为numpy的矢量化(vectorization)。 1.1 大小相等的数组运算 描述 大小相等的数组指shape相等的数组。大小相等的数组之间的任…

使用apifox创建一个Mock Server Api 接口

安装 下载 Apifox - API 文档、调试、Mock、测试一体化协作平台。拥有接口文档管理、接口调试、Mock、自动化测试等功能&#xff0c;接口开发、测试、联调效率&#xff0c;提升 10 倍。最好用的接口文档管理工具&#xff0c;接口自动化测试工具。 创建mock api项目中使用 创建项…