以下思路更详细解析来自于:代码随想录 (programmercarl.com)
LeetCode T669 修剪二叉搜索树
题目链接:669. 修剪二叉搜索树 - 力扣(LeetCode)
题目思路
这题我们有几个思路需要避坑,首先我们不能这样想,比如遇见比low值还小的节点值,不能直接返回null,而是考虑该节点的右子树有没有符合题目需求的节点值存在,同理删除右节点的时候应该考虑它的左子树有没有比该节点大的节点值存在
假设我们要删除[1,3]的数据,如上例,[1, 3]区间在二叉搜索树的中可不是单纯的节点3和左孩子节点0就决定的,还要考虑节点0的右子树。
在上图中我们发现节点0并不符合区间要求,那么将节点0的右孩子 节点2 直接赋给 节点3的左孩子就可以了(就是把节点0从二叉树中移除),如图:
1.确定参数和返回值
直接使用原函数即可
2.确定终止条件
if(root == null) { return null; } if(root.val<low) { return trimBST(root.right,low,high); } if(root.val>high) { return trimBST(root.left,low,high); }
3.确定单次递归思路
root.left = trimBST(root.left,low,high); root.right = trimBST(root.right,low,high); return root;
题目代码
class Solution { public TreeNode trimBST(TreeNode root, int low, int high) { if(root == null) { return null; } if(root.val<low) { return trimBST(root.right,low,high); } if(root.val>high) { return trimBST(root.left,low,high); } root.left = trimBST(root.left,low,high); root.right = trimBST(root.right,low,high); return root; } }
LeetCode T108将有序数组转化为二叉搜索树
题目链接 108. 将有序数组转换为二叉搜索树 - 力扣(LeetCode)
题目思路
如果给定一个数组,我们很容易就能想到使用双指针写法来解决问题,但是这道题是一道二叉搜索树的问题,我们就可以使用相似的讨论来解决问题,我们仍然用递归+双指针来解决问题
这题强调了是平衡二叉树,并且是排好升序的二叉树,所以要进行左右子树的分割,注意区间
注意定义数组区间,是左开右闭区间还是闭区间
1.函数的返回值和参数类型
TreeNode sort(int[] nums,int left,int right)
2.函数的终止条件
if(left>=right) { return null; }
3.函数的递归
if(right - left == 1) { return new TreeNode(nums[left]); } int mid = left+(right - left)/2; TreeNode node = new TreeNode(nums[mid]); node.left = sort(nums,left,mid); node.right = sort(nums,mid+1,right); return node;
题目代码
class Solution { public TreeNode sortedArrayToBST(int[] nums) { return sort(nums,0,nums.length); } TreeNode sort(int[] nums,int left,int right) { if(left>=right) { return null; } if(right - left == 1) { return new TreeNode(nums[left]); } int mid = left+(right - left)/2; TreeNode node = new TreeNode(nums[mid]); node.left = sort(nums,left,mid); node.right = sort(nums,mid+1,right); return node; } }
T538 把二叉搜索树转化为累加树
题目链接 538. 把二叉搜索树转换为累加树 - 力扣(LeetCode)
题目思路
这题和上题思路类似,使用双指针,不过这里只用一个pre记录上一个节点的数值即可,避免了去判断指针是否为空的过程,按照右中左过程进行操作即可.
1.函数的参数和返回值
无序返回值,直接操作root即可
void travsal(TreeNode root)
2.函数的终止条件
if(root == null) { return; }
3.函数的单层递归逻辑
travsal(root.right); root.val += pre; pre = root.val; travsal(root.left);
题目代码
class Solution { int pre = 0; public TreeNode convertBST(TreeNode root) { travsal(root); return root; } void travsal(TreeNode root) { if(root == null) { return; } travsal(root.right); root.val += pre; pre = root.val; travsal(root.left); } }