网站负责人核验照片o2o好网站
web/
2025/9/25 15:50:33/
文章来源:
网站负责人核验照片,o2o好网站,班级文化墙创意设计图片,盐城专业做网站的公司哪家好修剪二叉搜索树
给定一个二叉搜索树#xff0c;同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树#xff0c;使得所有节点的值在[L, R]中 (RL) 。你可能需要改变树的根节点#xff0c;所以结果应当返回修剪好的二叉搜索树的新的根节点。 最直接的想法#xff0…修剪二叉搜索树
给定一个二叉搜索树同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树使得所有节点的值在[L, R]中 (RL) 。你可能需要改变树的根节点所以结果应当返回修剪好的二叉搜索树的新的根节点。 最直接的想法遍历树然后找到root-val在[L,R]以外的节点删除通过递归处理返回根节点
如果此时简单的给出这种代码 root-left trimBST(root-left, low, high);root-right trimBST(root-right, low, high); 就会忽视掉当前节点不在范围内但是节点左(右)子树可能在范围内的情况
如下图所示 也就是在删除节点时还要对其子树进行判断至于实现方式可以参考上一题的子树嫁接方法无须重构二叉树结构
下面写递归三部曲
首先确定递归函数参数和返回值遍历整棵树做修改其实不需要返回值也可以完成修剪其实就是从二叉树中移除节点的操作但是有返回值更方便可以通过递归函数的返回值来移除节点不需要额外操作
其次确定终止条件修剪的操作并不是在终止条件进行的所以就是遇到空节点返回就可以了
最后确定单层递归的逻辑嫁接子树此处不再赘述
递归代码如下 TreeNode* traversal(TreeNode* root, int L, int R){if(root NULL) return NULL;if(root-val L){//节点值小于左边边界值TreeNode* tempNode traversal(root-right, L, R);//此节点右子树中寻找所有大于L的值的节点继续嵌套递归修剪右子树return tempNode;}if(root-val R) return traversal(root-left, L, R);//同理并非直接return子树而是修剪过后再returnroot-left traversal(root-left, L, R);//对符合区间条件的根节点左右子树进行操作root-right traversal(root-right, L, R);return root;}将有序数组转换为二叉搜索树
将一个按照升序排列的有序数组转换为一棵高度平衡二叉搜索树。
本题中一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例: 按题目要求切割数组得到平衡二叉搜索树则从数组中间作为根节点开始切割
同时注意循环不变量因为这里是需要不断对数组进行切割直到子数组的长度为一
遍历代码如下 TreeNode* traversal(vectorint nums, int L, int R){//确定函数参数和返回值//这里选择左闭右开的切割区间则子区间停止切割的终止条件即是数组长度等于零的时候if(L R) return NULL;//单层递归逻辑int mid (R-L)/2L;//防止int溢出TreeNode* root new TreeNode(nums[mid]);//确定根节点root-left traversal(nums, L, mid);//左闭右开root-right traversal(nums, mid1, R);return root;}把二叉搜索树转化为累加树
给出二叉 搜索 树的根节点该树的节点值各不相同请你将其转换为累加树Greater Sum Tree使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
提醒一下二叉搜索树满足下列约束条件
节点的左子树仅包含键 小于 节点键的节点。 节点的右子树仅包含键 大于 节点键的节点。 左右子树也必须是二叉搜索树。
示例 1 输入[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]输出[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
示例 2
输入root [0,null,1]输出[1,null,1]
示例 3
输入root [1,0,2]输出[3,3,2]
示例 4
输入root [3,2,4,1]输出[7,9,4,10]
提示
树中的节点数介于 0 和 104 之间。每个节点的值介于 -104 和 104 之间。树中的所有值互不相同 。给定的树为二叉搜索树。
如果给定的是一个有序数组则[1, 2, 3, 4]的结果就是[10, 9, 7, 4]那二叉树呢
从二叉搜索树的最大值开始往前递加无疑就是处理顺序的改变即右中左的顺序来遍历整个二叉搜索树即反中序遍历
则递归代码如下 int sum 0;//记录前一个节点的数值void traversal(TreeNode* cur){//确定函数参数和返回值遍历整棵树且无须对返回值进行处理if(!cur) return;//确定终止条件为空返回//if(cur-right) sum cur-right-val; 单层逻辑traversal(cur-right);cur-val sum;sum cur-val;//更新sum//if(cur-left) sum cur-left-valtraversal(cur-left);} 整体代码如下
/*** Definition for a binary tree node.* 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 {
private:int sum 0;//记录前一个节点的数值void traversal(TreeNode* cur){//确定函数参数和返回值遍历整棵树且无须对返回值进行处理if(!cur) return;//确定终止条件为空返回//if(cur-right) sum cur-right-val; 单层逻辑traversal(cur-right);cur-val sum;sum cur-val;//更新sum//if(cur-left) sum cur-left-valtraversal(cur-left);}
public:TreeNode* convertBST(TreeNode* root) {sum 0;traversal(root);return root;}
};总结
递归和迭代的思想都要熟悉
递归
首先是熟知递归函数的参数和返回值
如何利用才能使算法的性能最优化例如对返回节点类型、传入int替代vector
(见Day 18)
如果需要搜索整棵二叉树且不用处理递归返回值递归函数就不要返回值这种情况就是本文下半部分介绍的113.路径总和ii
如果需要搜索整棵二叉树且需要处理递归返回值递归函数就需要返回值 这种情况我们在236. 二叉树的最近公共祖先 (opens new window)中介绍
如果要搜索其中一条符合条件的路径那么递归一定需要返回值因为遇到符合条件的路径了就要及时返回
其次是关于递归函数的终止条件
有时候终止条件并不是简单的对处理节点判空即可需要根据具体情境进行判断
最后是递归函数的单层遍历逻辑
二叉树题目的逻辑往往不算很难大多时候可以理解为对一个遍历顺序特殊的数组进行处理所以遍历顺序尤为重要
在构建二叉树的节点的时候一定是选择从根节点开始中左右即前序遍历
在面对二叉搜索树时一定是选择中序遍历左中右这样才能充分利用二叉搜索树的有序性质
求普通二叉树的属性的时候一般采取后序遍历左右中因为需要返回中节点进行处理
迭代
迭代最主要的思想就是用栈来模拟树的逻辑通过不断的push pop得到理想中的出栈顺序
一般在涉及到递归不是很好处理返回值的时候使用迭代层序遍历就是一个典型的例子。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/81697.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!