删除二叉搜索树中的节点
题目:450
-
需要对二叉树结构进行修改
-
递归三部曲,前两个容易
-
返回值和参数:参考上一个插入节点的题,通过递归返回值删除节点
-
结束条件:遇空节点返回
-
单层递归逻辑:
-
根据二叉搜素树的性质找被删除节点在的位置
-
主要是要考虑到以下五种情况
-
第一种情况:没找到删除的节点,遍历到空节点直接返回了
-
找到删除的节点
- 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
- 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
- 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
- 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
TreeNode cur = root.right;
while (cur.left != null) {
cur = cur.left;
}
cur.left = root.left;
root = root.right;
return root;
修剪二叉搜索树
题目:669
-
单层逻辑上面,不用想的那么复杂,例如我们发现节点root并不符合区间要求,就去继续找符合条件的节点,根据root.val是太少还是太多,选择新的递归范围是root.left 还是 root.right
-
这个方法的单看下来,好像就是返回在区间范围内的节点,毕竟不在区间范围内的,都被拖去去找它那可能在区间内的节点了
-
如果root(当前节点)的元素小于low的数值,那么应该递归右子树,并返回右子树符合条件的头结点。
if (root.val < low) { return trimBST(root.right, low, high);//寻找在区间内的节点 } -
如果root(当前节点)的元素大于high的,那么应该递归左子树,并返回左子树符合条件的头结点。
将有序数组转为二叉搜索树
题目:108
-
因为已经是升序了,还要保持高度差,所以直接每次就取“当前数组”的nums[mid]为中,然后mid左边做左子树,mid右边做右子树,不断递归
-
递归返回值和参数:
public TreeNode makeTree(int[] nums, int left, int right) -
终止条件:无节点可创造
if (left > right) {
return null;
}
- 单层递归逻辑:
int mid = (left + right) / 2;
TreeNode root = new TreeNode(nums[mid]);
root.left = makeTree(nums, left, mid - 1);
root.right = makeTree(nums, mid + 1, right);
return root;
把二叉搜索树转换为累加树
题目:538
- 感觉是一款顺序为右中左
- 不需要递归函数的返回值,遍历一下整个树就行
public void convertBST1(TreeNode root)
- 需要有一个全局变量pre来保存此前累加的值(比当前节点值大的节点值和)
- 那么就按照平时递归遍历来就行,只不过把中节点的操作更新为了“更新节点值”和“更新累加值pre”
convertBST1(root.right);
sum += root.val;
root.val = sum;
convertBST1(root.left);