-
669修剪二叉搜索树
- 代码随想录 (programmercarl.com)
-
第一印象
- 简单的想法是利用中序遍历得到有序数组,再在数组中去掉区间外的值后重新生成二叉搜索树。这样这道题就类似于另外一道题了。
-
讲解观后感
- 递归法遇到界限外节点的处理方法是返回其相应子树。
小于界限返回左子树,大于界限返回右子树。直接返回nil会遗失子树上在范围内的值。
- 迭代法:从根节点向下找到的第一个符合范围内的节点就是新树的根节点,其下的所有节点即是原树中所有存在于区间的节点。
-
解题代码
- 递归
-
func trimBST(root *TreeNode, low int, high int) *TreeNode {
if root == nil {
return nil
}
if root.Val < low {
right := trimBST(root.Right, low, high)
return right
}
if root.Val > high {
left := trimBST(root.Left, low, high)
return left
}
root.Left = trimBST(root.Left, low, high)
root.Right = trimBST(root.Right, low, high)
return root
}
- 迭代
-
func trimBST(root *TreeNode, low int, high int) *TreeNode {
if root == nil {
return nil
}
for root != nil && (root.Val < low || root.Val > high) {
if root.Val < low {
root = root.Right
} else {
root = root.Left
}
}
cur := root
for cur != nil {
for cur.Left != nil && cur.Left.Val < low {
cur.Left = cur.Left.Right
}
cur = cur.Left
}
cur = root
for cur != nil {
for cur.Right != nil && cur.Right.Val > high {
cur.Right = cur.Right.Left
}
cur = cur.Right
}
return root
}
-
108有序数组转二叉搜索树
- 代码随想录 (programmercarl.com)
-
第一印象
- 因为是有序数组,所以可以很方便的找到中间结点。然后向下构建树即可。
-
讲解观后感
- 递归操作中利用双指针获得中间结点是很巧妙的方法。需要注意循环不变量原则,选择左闭右开还是左闭右闭要记得边界的调整
- 利用golang切片的特性,可以得到更简洁的代码。
-
解题代码
- 双指针递归
-
func sortedArrayToBST(nums []int) *TreeNode {
root := linkNode(nums, 0, len(nums)-1)
return root
}
func linkNode(nums []int, left int, right int) *TreeNode {
if left>right {
return nil
}
nodeIdx := left + (right - left)/2
node := &TreeNode{Val:nums[nodeIdx]}
node.Left = linkNode(nums, left, nodeIdx-1)
node.Right = linkNode(nums, nodeIdx+1, right)
return node
}
- 切片递归
-
func sortedArrayToBST(nums []int) *TreeNode {
if len(nums) == 0 {
return nil
}
idx := len(nums)/2
root := &TreeNode{Val: nums[idx]}
root.Left = sortedArrayToBST(nums[:idx])
root.Right = sortedArrayToBST(nums[idx+1:])
return root
}
-
538二叉搜索树转累加树
- 代码随想录 (programmercarl.com)
-
第一印象
- 想法是可以利用中序遍历先得到有序数组,然后通过倒序累加的方式得到累加和的新数组。因为原节点值各不相同,可以利用两个数组构建map。然后通过遍历修改节点数值。
-
讲解观后感
- 直接利用右中左的遍历顺序就可以一次完成求得的和值和遍历结点的过程。只需要一个变量存储和值即可。
-
解题代码
-
var pre int
func convertBST(root *TreeNode) *TreeNode {
pre = 0
traversal(root)
return root
}
func traversal(cur *TreeNode) {
if cur == nil {
return
}
traversal(cur.Right)
cur.Val += pre
pre = cur.Val
traversal(cur.Left)
}