Leetcode-二叉搜索树


q98 验证二叉搜索树


题目传送门


题解

使用前序遍历,使用dfs来遍历,其中二叉排序树应该满足左子树的所有节点都小于根节点,右子树的所有节点都大于根节点。所以递归函数的参数列表中维护着一个最大值和最小值,在左递归的时候,将最大值更新为当前节点,因为左子树中不应该出现比这个最大值更大的数;同时在右递归的时候,将最小值更新为当前节点,因为右子树中不应该出现比这个最小值更小的数。

func isValidBST(root *TreeNode) bool {
	return dfs(root, math.MinInt64, math.MaxInt64)
}

func dfs(root *TreeNode, min, max int) bool {
	if root == nil {
		return true
	}
	// 判断是否在这个区间内
	if root.Val <= min || root.Val >= max {
		return false
	}
	// 更新左递归的最大值为当前节点
	// 更新右递归的最小值为当前节点
	return dfs(root.Left, min, root.Val) && dfs(root.Right, root.Val, max)
}

q450 删除二叉搜索树中的节点


题目传送门


题解

删除BST中的节点,有以下三种情况:

1 如果key < root.Val,说明要删除的节点在BST的左子树,那么递归去左子树删除即可
2 如果key > root.Val,说明要删除的节点在BST的右子树,那么递归去右子树删除即可
3 如果key = root.Val,说明要删除的节点就是本节点,这一类又分以下三种情况:

  • 无左右子树,直接删除即可
  • 有右子树,将当前节点与后继节点替换,然后递归的在右子树中删除该后继节点
  • 有左子树,将当前节点与前趋节点替换,然后递归的在左子树中删除该前趋节点

找前趋节点的方法,就是在当前节点的左子树中不断递归遍历它的右节点,直到右结点为空,当前节点就是前趋节点。
找后继节点的方法就是在当前节点的右子树中不断递归遍历它的左节点,直到左节点为空,当前节点就是后继节点。

func deleteNode(root *TreeNode, key int) *TreeNode {
	if root == nil {
		return nil
		// 往左子树找
	} else if key < root.Val {
		root.Left = deleteNode(root.Left, key)
		// 往右子树找
	} else if key > root.Val {
		root.Right = deleteNode(root.Right, key)
		// 当前节点的值是key
	} else {
		// 无左右子树,直接删除
		if root.Left == nil && root.Right == nil {
			root = nil
			// 有右子树,将后继节点换到当前位置,然后删除后继节点
		} else if root.Right != nil {
			// 替换
			root.Val = Successor(root).Val
			// 删除后继节点
			root.Right = deleteNode(root.Right, root.Val)
			// 有左子树,将前趋节点换到当前位置,然后删除前趋节点
		} else {
			root.Val = Predecessor(root).Val
			root.Left = deleteNode(root.Left, root.Val)
		}
	}
	return root
}

// Predecessor 寻找前趋节点
func Predecessor(node *TreeNode) *TreeNode {
	pre := node.Left
	for pre.Right != nil {
		pre = pre.Right
	}
	return pre
}

// Successor 寻找后继节点
func Successor(node *TreeNode) *TreeNode {
	post := node.Right
	for post.Left != nil {
		post = post.Left
	}
	return post
}

q538 把二叉搜索树转换为累加树


题目传送门


题解

这道题其实是要把根节点累加上右子树的和,然后左子树累加上根节点+右子树的和.
即:

root.Val = root.Val + root.Right.Val
root.Left.Val = root.Val

使用反向中序遍历即可.

func convertBST(root *TreeNode) *TreeNode {
	sum := 0
	var traversal func(root *TreeNode)
	traversal = func(root *TreeNode) {
		if root != nil {
			traversal(root.Right)
			sum += root.Val
			root.Val = sum
			traversal(root.Left)
		}
	}
	traversal(root)
	return root
}

q701 二叉搜索树中的插入操作


题目传送门


题解

插入时与当前节点进行比较,如果小于当前节点就继续遍历插入到左子树中,如果大于当前节点就继续遍历插入到右子树中。

func insertIntoBST(root *TreeNode, val int) *TreeNode {
	if root == nil {
		return &TreeNode{Val: val}
	}
	p := root
	for p != nil {
		if val < p.Val {
			if p.Left == nil {
				p.Left = &TreeNode{Val: val}
				break
			}
			p = p.Left
		} else {
			if p.Right == nil {
				p.Right = &TreeNode{Val: val}
				break
			}
			p = p.Right
		}
	}
	return root
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值