669 修建二叉树
func trimBST(root *TreeNode, low int, high int) *TreeNode {
// 暴力笨方法, 遍历,删除范围之外的节点
if root == nil {
return nil
}
var res []int
inorder(root, &res)
for _, v := range res {
if v > high || v < low {
root = deleteBST(root, v)
}
}
return root
}
func inorder(root *TreeNode, res *[]int) {
if root == nil {
return
}
inorder(root.Left, res)
*res = append(*res, root.Val)
inorder(root.Right, res)
}
func deleteBST(root *TreeNode, val int) *TreeNode {
if root == nil {
return nil
}
cur := root
var pre *TreeNode
for cur != nil && cur.Val != val {
pre = cur
if cur.Val > val {
cur = cur.Left
}else {
cur = cur.Right
}
}
if cur == nil {
return root
}
// 叶子节点,直接删除
if cur.Left == nil && cur.Right == nil {
if pre == nil {
return nil
}else if pre.Left == cur {
pre.Left = nil
}else if pre.Right == cur {
pre.Right = nil
}
}
// 只有一个子节点
if cur.Left != nil && cur.Right == nil {
if pre == nil {
root = cur.Left
}else if pre.Left == cur {
pre.Left = cur.Left
}else if pre.Right == cur {
pre.Right = cur.Left
}
}
if cur.Left == nil && cur.Right != nil {
if pre == nil {
root = cur.Right
}else if pre.Left == cur {
pre.Left = cur.Right
}else if pre.Right == cur {
pre.Right = cur.Right
}
}
// 两个子节点
if cur.Left != nil && cur.Right != nil {
// 1, 找到中序后继
var inOrderpre, inOrderNext = cur, cur.Right // 分别指向中序后继的前一个,以及中序后继
for inOrderNext.Left != nil {
inOrderpre = inOrderNext
inOrderNext = inOrderNext.Left
}
fmt.Println(inOrderpre, inOrderNext)
// 2,将中序后继值赋给cur
cur.Val = inOrderNext.Val
// 3, 删除中序后继
// 3.1 中序后继 是叶子节点 3.2 中序后继有一个右子节点 1 所以只需要判断右子节点是否为空来判断两种情况
// \
// 3
if inOrderpre.Left == inOrderNext {
if inOrderNext.Right == nil {
inOrderpre.Left = nil
}else {
inOrderpre.Left = inOrderNext.Right
}
} else if inOrderpre.Right == inOrderNext {
if inOrderNext.Right == nil {
inOrderpre.Right = nil
} else {
inOrderpre.Right = inOrderNext.Right
}
}
}
return root
}
func trimBST(root *TreeNode, low int, high int) *TreeNode {
// 优雅的递归处理逻辑 核心是遇到要删除的节点,那么将该节点左或者右子树付给上一个节点
if root == nil {
return nil
}
var left, right *TreeNode
if root.Val > high { // 此时root的左子树可能存在小于high的节点,所以应该去递归左子树
left = trimBST(root.Left, low, high )
return left
}
if root.Val < low {
right = trimBST(root.Right, low, high)
return right
}
// root在区间之内
root.Left = trimBST(root.Left, low, high)
root.Right = trimBST(root.Right, low, high)
return root
}
有序数组转二叉搜索树
func sortedArrayToBST(nums []int) *TreeNode {
// 递归思路,中间的节点就是根节点,然后左右递归找根
if len(nums) == 0 {
return nil
}
mid := len(nums) / 2
var left, right, root *TreeNode
if mid > 0 {
left = sortedArrayToBST(nums[0: mid])
}
if mid + 1 < len(nums){
right = sortedArrayToBST(nums[mid+1: len(nums)])
}
root = &TreeNode{nums[mid], left, right}
return root
}
二叉搜索树转换为累加树
// 关键在于读懂题目
func convertBST(root *TreeNode) *TreeNode {
// 中序倒过来遍历,然后双指针相加
if root == nil {
return nil
}
var sum int
inOrdersum(root, &sum)
return root
}
func inOrdersum(root *TreeNode, sum *int) {
if root == nil {
return
}
inOrdersum(root.Right, sum)
*sum += root.Val
root.Val = *sum
inOrdersum(root.Left, sum)
}