刷题顺序按照代码随想录建议
题目描述
英文版描述
Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.
Basically, the deletion can be divided into two stages:
- Search for a node to remove.
- If the node is found, delete the node.
Example 1:
Input: root = [5,3,6,2,4,null,7], key = 3 Output: [5,4,6,2,null,null,7] Explanation: Given key to delete is 3. So we find the node with value 3 and delete it. One valid answer is [5,4,6,2,null,null,7], shown in the above BST. Please notice that another valid answer is [5,2,6,null,4,null,7] and it's also accepted.
Example 2:
Input: root = [5,3,6,2,4,null,7], key = 0 Output: [5,3,6,2,4,null,7] Explanation: The tree does not contain a node with value = 0.
Example 3:
Input: root = [], key = 0 Output: []
Constraints:
- The number of nodes in the tree is in the range
[0, 10^4]
. -10^5 <= Node.val <= 10^5
- Each node has a unique value.
root
is a valid binary search tree.-10^5 <= key <= 10^5
.
英文版地址
中文版描述
给定一个二叉搜索树的根节点 root 和一个值 key ,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
- 首先找到需要删除的节点;
- 如果找到了,删除它。
示例 1:
输入: root = [5,3,6,2,4,null,7], key = 3 输出: [5,4,6,2,null,null,7] 解释: 给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。 一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。 另一个正确答案是 [5,2,6,null,4,null,7]。
示例 2:
输入: root = [5,3,6,2,4,null,7], key = 0 输出: [5,3,6,2,4,null,7] 解释: 二叉树不包含值为 0 的节点
示例 3:
输入: root = [], key = 0 输出: []
提示:
- 节点数的范围
[0, 10^4]
. -10^5 <= Node.val <= 10^5
- 节点值唯一
root
是合法的二叉搜索树-10^5 <= key <= 10^5
中文版地址
解题方法
递归法
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return null;
}
if (root.val == key) {
if (root.left == null && root.right != null) {
return root.right;
}else if (root.left != null && root.right == null) {
return root.left;
}else if (root.left == null && root.right == null) {
return null;
}else {
TreeNode right = root.right;
while (right.left != null) {
right = right.left;
}
right.left = root.left;
return root.right;
}
}
if (root.val > key) {
root.left = deleteNode(root.left, key);
}
if (root.val < key) {
root.right = deleteNode(root.right, key);
}
return root;
}
}
复杂度分析
- 时间复杂度:O(n),其中 n 是二叉树的节点数,每一个节点恰好被遍历一次
- 空间复杂度:O(n),为递归过程中栈的开销,平均情况下为 O(logn),最坏情况下树呈现链状,为 O(n)
迭代法
迭代法的关键在于保存当前遍历节点的父节点,这样才能删除它
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
TreeNode cur = root;
TreeNode parent = null;
while (cur != null && cur.val != key) {
if (cur.val < key) {
parent = cur;
cur = cur.right;
} else {
parent = cur;
cur = cur.left;
}
}
if (cur == null) {
return root;
} else if (cur.right == null && cur.left == null) {
cur = null;
} else if (cur.right != null && cur.left == null) {
cur = cur.right;
} else if (cur.right == null && cur.left != null) {
cur = cur.left;
} else {
TreeNode r = cur.right;
if (r != null) {
while (r.left != null) {
r = r.left;
}
r.left = cur.left;
cur = cur.right;
}
}
if (parent == null) {
return cur;
}
if (parent != null && parent.left != null && parent.left.val == key) {
parent.left = cur;
}
if (parent != null && parent.right != null && parent.right.val == key) {
parent.right = cur;
}
return root;
}
}
复杂度分析
- 时间复杂度:O(n),其中 n 是二叉树的节点数,每一个节点恰好被遍历一次
- 空间复杂度:O(1)