代码随想录day21 || 669 修剪二叉搜索树,108 将有序数组转化为二叉搜索树,538 二叉搜索树转化为累加树

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)
}
posted @ 2024-08-06 11:51  周公瑾55  阅读(20)  评论(0)    收藏  举报