题目背景
在基础比较差的情况下,对这个题目的理解时候有点问题,于是通过debug的方法倒推出出题的思路,反之回来思考就变得很清晰。话不多说,见实例:
原题链接:https://leetcode-cn.com/problems/delete-node-in-a-bst/description/
题目描述
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
首先找到需要删除的节点;
如果找到了,删除它。
说明: 要求算法时间复杂度为 O(h),h 为树的高度。
示例:
root = [8,5,6,3,7,null,9]
key = 5
8
/ \
5 6
/ \ \
3 7 9
给定需要删除的节点值是 5,所以我们首先找到 5 这个节点,然后删除它。
一个正确的答案是 [8,7,6,3,null,null,9], 如下图所示。
8
/ \
7 6
/ \
3 9
另一个正确答案是 [8,3,6,null,7,null,9]。
8
/ \
3 6
\ \
7 9
思路
step1:假如没有子节点,直接删除
step2:假如要删除的节点只有一个子节点,那么删除节点后,就用这个子节点替换
step3:假如要删除的节点有两个子节点,那么从删除节点的右分支查找最小值,将其要删除的节点替换
来,直接上代码:
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return null;
}
if (key < root.val){
root.left = deleteNode(root.left,key);
return root;
}else if (key > root.val){
root.right = deleteNode(root.right,key);
return root;
}else {
if (root.left == null || root.right == null){
root = root.left == null?root.right:root.left;
}else {
TreeNode cur = root.right;
while (cur.left != null){
cur = cur.left;
}
root.val = cur.val;
root.right = deleteNode(root.right,cur.val);
}
}
return root;
}
}
先用暂时能想到的粗鄙的方式给树赋值,然后咱们开始debug
public static void main(String[] args) {
Solution solution = new Solution();
TreeNode treeNode1 = new TreeNode(8);
TreeNode treeNode2 = new TreeNode(5);
TreeNode treeNode3 = new TreeNode(6);
TreeNode treeNode4 = new TreeNode(3);
TreeNode treeNode5 = new TreeNode(7);
TreeNode treeNode6 = new TreeNode(9);
treeNode1.left = treeNode2;
treeNode1.right = treeNode3;
treeNode2.left = treeNode4;
treeNode2.right = treeNode5;
treeNode3.left =null;
treeNode3.right = treeNode6;
TreeNode treeNode = solution.deleteNode(treeNode1, 5);
}
首先,root.val的值是8,小于key的值5,进入迭代
这个时候,root.val就是5了,这时候就进入下一个分支,首先判断是否有子分支,这时候的判断是有子分支的,然后我们这里判断右分支是否有左分支,如果有的话要继续迭代,没有的话那么我们就将右分支的值覆盖要删除的值,可以看到这时候,我们的右分支就替代了原来的要删除的位置。
但是右分支有个7,发现没有删除,那么我们就要来操作右分支,继续往下迭代,
重新走到这一步,发现没有子分支了,那么就会给他一个null。这时候,顺序就对上了。跟着这个思路走,可以理清操作流程。
当对这类题目有了明确的思路,可以自己走得通流程图,那么就不需要通过这种方式来理解,可以通过自己的思路,去更好的探究这些题目。
希望可以帮到你!