LeetCode450.删除二叉搜索树中的节点Golang版
1. 问题描述
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
首先找到需要删除的节点;
如果找到了,删除它。
说明: 要求算法时间复杂度为 O(h),h 为树的高度。
2. 思路
2.1. 递归
- 确定递归函数参数和返回值
func deleteNode(root *TreeNode, key int) *TreeNode
- 确定结束条件
if root == nil {
return root
}
- 确定单层递归逻辑(五种情况)
- 没找到删除的节点,遍历到空节点直接返回
- 要删除节点的左右孩子为空,直接删除节点
- 要删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位
- 要删除节点的右孩子为空,左孩子不为空,删除节点, 左孩子补位
- 要删除节点的左右孩子都不为空,右孩子补位,左孩子连接到到右孩子做左侧节点上
3. 代码
3.1. 递归代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func deleteNode(root *TreeNode, key int) *TreeNode {
if root == nil {
return root
}
// root为要删除的节点
if root.Val == key {
// 1. 左孩子为空,返回右孩子
if root.Left == nil {
return root.Right
}
// 2. 右孩子为空,返回左孩子
if root.Right == nil {
return root.Left
}
// 3. 左右孩子不为空,找到右孩子的最左侧孩子
cur := root.Right
for cur.Left != nil {
cur = cur.Left
}
// 把root左孩子,接到最左侧孩子的左侧
cur.Left = root.Left
// 把root更新为root的右孩子
root = root.Right
return root
}
if root.Val < key {
root.Right = deleteNode(root.Right, key)
}
if root.Val > key {
root.Left = deleteNode(root.Left, key)
}
return root
}