第六章 二叉树part08
669. 修剪二叉搜索树
这道题目比较难,比 添加增加和删除节点难的多,建议先看视频理解。
题目链接/文章讲解: https://programmercarl.com/0669.%E4%BF%AE%E5%89%AA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html
视频讲解: https://www.bilibili.com/video/BV17P41177ud
108.将有序数组转换为二叉搜索树
本题就简单一些,可以尝试先自己做做。
https://programmercarl.com/0108.%E5%B0%86%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E8%BD%AC%E6%8D%A2%E4%B8%BA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html
视频讲解:https://www.bilibili.com/video/BV1uR4y1X7qL
538.把二叉搜索树转换为累加树
本题也不难,在 求二叉搜索树的最小绝对差 和 众数 那两道题目 都讲过了 双指针法,思路是一样的。
https://programmercarl.com/0538.%E6%8A%8A%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E8%BD%AC%E6%8D%A2%E4%B8%BA%E7%B4%AF%E5%8A%A0%E6%A0%91.html
视频讲解:https://www.bilibili.com/video/BV1d44y1f7wP
总结篇
好了,二叉树大家就这样刷完了,做一个总结吧
https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E6%80%BB%E7%BB%93%E7%AF%87.html
669. 修剪二叉搜索树
题目链接
https://leetcode.cn/problems/trim-a-binary-search-tree/description/
解题思路
不符合的区间要删除掉,但是当前节点不符合,根据二叉搜索树的特性,左是小于当前节点的值,右是大于当前节点的值的,所以子树可能符合也可能不符合这个区间,那么就要递归的去找到符合的区间的节点,二叉搜索树的特性左小右大,当前节点值大于最大值去左区间找,当前节点值小于最小值去右区间找。
递归通用的思想解题,递归函数的返回值赋值给上层的父节点,返回一颗符合区间的二叉搜索树。
不符合区间的节点删除,符合区间的节点,返回给父节点进行赋值即可,
即递归的是左返回值赋值给root.left
递归的是右返回值赋值给root.right
可以画图模拟下,符合区间的节点直接赋值给父节点是符合二叉搜索树的特性的。
code
//1.递归参数和返回值,返回这颗树的根节点,依然用递归函数的下层值赋值给父节点,以便做删除操作
public TreeNode trimBST(TreeNode root, int low, int high) {
if(root==null){
return null;
}
//判断当前节点是否在[low,high]区间内,如果不在,要递归直到找到在区间符合的子树
//1.最小值大于根节点说明区间一定是在右才能找到,二叉搜索的特性,当前节点的值是大于左子树的 小于右子树
if(low>root.val){
TreeNode right=trimBST(root.right,low,high);
return right;
}
//2.最大值小于根节点说明区间一定是在左才能找到
if(high<root.val){
TreeNode left=trimBST(root.left,low,high);
return left;
}
//3.递归给父节点赋值
root.left=trimBST(root.left,low,high);
root.right=trimBST(root.right,low,high);
return root;
}
108.将有序数组转换为二叉搜索树
题目链接
https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree/description/
解题思路
这题直接就写出来了,没考虑题目说的平衡二叉树,不如不说平衡,那么有序数组父节点一直指向右也是二叉搜索树,就是线性的了,如果要这么做的话,是不是本题意义就不大了。
每次找中间节点分割点就可以了,分割数组,左数组,右数组,在找中间节点
二叉搜索树单调递增就是中序遍历,每次取数组的中间节点就是中节点的值
使用前序遍历 递归给根节点赋值
code
public TreeNode sortedArrayToBST(int[] nums) {
if(nums==null||nums.length==0){
return null;
}
return recursion(nums,0,nums.length-1);
}
public TreeNode recursion(int[] nums ,int left,int right){
if(left>right){
return null;
}
int mid =left+(right-left)/2;
TreeNode root=new TreeNode(nums[mid]);
root.left=recursion(nums,left,mid-1);
root.right=recursion(nums,mid+1,right);
return root;
}
理解 如果数组是偶数要分割的数组长度为偶数的时候节点取哪个? [-10,-3,0,5,9]
都可以的
538.把二叉搜索树转换为累加树
题目链接
https://leetcode.cn/problems/convert-bst-to-greater-tree/description/
解题思路
二叉搜索树中序遍历是单调递增的,题目要累加大于等于当前节点的值,
如果是数组的话就是从后向前遍历,当前值依次累加到前一个,
但这是二叉树
左中右 中序遍历,单调递增从小到大
那么右中左 反中序遍历,不就是单调递减从大到小了嘛,就可以把上一个节点的值加入到当前节点,然后就顺序累加了, 只需一个前指针记录前一个节点的值,当前节点的值加上前一个节点的值就解决了。
code
//二叉搜索树,中序遍历是单调递增的 做到累加就是把数组的后一个节点值依次和前一个节点值相加
//反中序遍历 右中左
public TreeNode convertBST(TreeNode root) {
traversal(root);
return root;
}
//定义一个全局遍历记录前一个节点值,方便下一个节点值相加
int preValue=0;
public void traversal(TreeNode node){
if(node==null){
return;
}
traversal(node.right);
node.val+=preValue;
preValue=node.val;
traversal(node.left);
}