LeetCode——删除二叉搜索树中的节点

Q:给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。一般来说,删除节点可分为两个步骤:

首先找到需要删除的节点;
如果找到了,删除它。
说明: 要求算法时间复杂度为 O(h),h 为树的高度。

示例:

root = [5,3,6,2,4,null,7]
key = 3

5
/ \
3 6
/ \ \
2 4 7

给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。

一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。

5
/ \
4 6
/ \
2 7

另一个正确答案是 [5,2,6,null,4,null,7]。

5
/ \
2 6
\ \
4 7

A:

如果 key > root.val,说明要删除的节点在右子树,root.right = deleteNode(root.right, key)。
如果 key < root.val,说明要删除的节点在左子树,root.left = deleteNode(root.left, key)。
如果 key == root.val,则该节点就是我们要删除的节点,则:
如果该节点是叶子节点,则直接删除它:root = null。
如果该节点不是叶子节点且有右节点,则用它的后继节点的值替代 root.val = successor.val,然后删除后继节点。
如果该节点不是叶子节点且只有左节点,则用它的前驱节点的值替代 root.val = predecessor.val,然后删除前驱节点。
返回 root。

 1     public TreeNode deleteNode(TreeNode root, int key) {
 2         if (root == null)
 3             return null;
 4         if (key > root.val) {
 5             root.right = deleteNode(root.right, key);
 6         } else if (key < root.val) {
 7             root.left = deleteNode(root.left, key);
 8         } else {
 9             if (root.left == null && root.right == null) {
10                 root = null;
11             } else if (root.left == null) {
12                 root.val = rightMin(root);
13                 root.right = deleteNode(root.right, root.val);
14             } else {
15                 root.val = leftMax(root);
16                 root.left = deleteNode(root.left, root.val);
17             }
18         }
19         return root;
20     }
21 
22     private int leftMax(TreeNode root) {
23         root = root.left;
24         while (root.right != null)
25             root = root.right;
26         return root.val;
27     }
28 
29     private int rightMin(TreeNode root) {
30         root = root.right;
31         while (root.left != null)
32             root = root.left;
33         return root.val;
34     }

猜你喜欢

转载自www.cnblogs.com/xym4869/p/12703676.html