669. 修剪二叉搜索树
1.删除节点可以靠返回值来操作,返回其子节点就是删除了该节点
所以返回值选择为节点,要处理空节点,否则正常范围内返回根节点
public TreeNode trimBST(TreeNode root, int low, int high) {
if (root == null) {
return null;
}
2. 需要遍历整颗树
3. 遇到比范围小的根节点,删除该节点和其左子树(左子树比根节点小),返回右子树。但是右子树中可能还存在不符合范围的值,所以应该返回右子树的遍历函数(遍历整颗树)
if (root.val < low) {
return trimBST(root.right, low, high);
}
4. 遇到比范围大的根节点同理
if (root.val > high) {
return trimBST(root.left, low, high);
}
5.遇到在范围内的根节点,不需要操作,直接按照整数遍历走就可以了
// root在[low,high]范围内
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
迭代法
class Solution {
//iteration
public TreeNode trimBST(TreeNode root, int low, int high) {
if(root == null)
return null;
//找到范围阈值内的节点
while(root != null && (root.val < low || root.val > high)){
if(root.val < low)
root = root.right;
else
root = root.left;
}
TreeNode curr = root;
//往左边找,当cur.left小于阈值范围时删除cur.left及其左节点cur.left.left,将其右节点的值赋予左节点(cur.left = cur.left.right)
//删除之后,因为cur.left.right仍然存在不有效节点的可能,接着向左遍历
//deal with root's left sub-tree, and deal with the value smaller than low.
while(curr != null){
while(curr.left != null && curr.left.val < low){
curr.left = curr.left.right;
}
curr = curr.left;
}
//go back to root;重新回到范围内
curr = root;
//对右边做同样的操作
//deal with root's righg sub-tree, and deal with the value bigger than high.
while(curr != null){
while(curr.right != null && curr.right.val > high){
curr.right = curr.right.left;
}
curr = curr.right;
}
return root;
}
}
108.将有序数组转换为二叉搜索树
debug:递归法如果stack overflow可能是进入了死循环,没有说明有关终止条件的部分出了问题
对于区间定义的循环不变量
通过递归函数的返回值来增删二叉树
538.把二叉搜索树转换为累加树
有序数组倒叙->中序遍历反过来右中左
class Solution {
int sum;
public TreeNode convertBST(TreeNode root) {
sum = 0;
convertBST1(root);
return root;
}
// 按右中左顺序遍历,累加即可
public void convertBST1(TreeNode root) {
if (root == null) {
return;
}
convertBST1(root.right);
sum += root.val;
root.val = sum;
convertBST1(root.left);
}
}
//迭代法
class Solution {
//DFS iteraion統一迭代法
public TreeNode convertBST(TreeNode root) {
int pre = 0;
Stack<TreeNode> stack = new Stack<>();
if(root == null) //edge case check
return null;
stack.add(root);
while(!stack.isEmpty()){
TreeNode curr = stack.peek();
//curr != null的狀況,只負責存node到stack中
if(curr != null){
stack.pop();
if(curr.left != null) //左
stack.add(curr.left);
stack.add(curr); //中
stack.add(null);
if(curr.right != null) //右
stack.add(curr.right);
}else{
//curr == null的狀況,只負責做單層邏輯
stack.pop();
TreeNode temp = stack.pop();
temp.val += pre;
pre = temp.val;
}
}
return root;
}
}
二叉树总结:
图源:代码随想录

- 二叉树:求最大深度(opens new window)
- 递归:后序,求根节点最大高度就是最大深度,通过递归函数的返回值做计算树的高度
- 二叉树:求最小深度(opens new window)
- 递归:后序,求根节点最小高度就是最小深度,注意最小深度的定义
class Solution {
/**
* 递归法,相比求MaxDepth要复杂点
* 因为最小深度是从根节点到最近**叶子节点**的最短路径上的节点数量
*/
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
int leftDepth = minDepth(root.left);
int rightDepth = minDepth(root.right);
if (root.left == null) {
return rightDepth + 1;
}
if (root.right == null) {
return leftDepth + 1;
}
// 左右结点都不为null
//都为null已经被包含,其实就是1
return Math.min(leftDepth, rightDepth) + 1;
}
}
-
递归:中序,清空结果集的技巧,遍历一遍便可求众数集合
- 递归:顺序无所谓,如果节点的数值在目标区间就是最近公共祖先
- 迭代:按序遍历
文章讲述了如何在二叉搜索树中进行节点删除(trimBST),使用递归和迭代方法处理范围限制,包括有序数组转换为二叉搜索树、累加树构建以及计算最大深度、最小深度和众数等问题。
331

被折叠的 条评论
为什么被折叠?



