题目1: 669. 修剪二叉搜索树
删除节点:
卫语句:如果当前节点 在边界范围内, return root
如果当前节点,左右子树皆为空, 直接返回nil
如果当前节点的值,大于右边界: 移除右边界 root.right = nil 左边界如何处理? 继续Recursive?
如果当前节点的值,小于左边界: 移除右边界 root.right = nil 左边界如何处理? 继续Recursive?
思路没错。 代码可以简化, 不用单独起删除节点的func。
建议: 画图来捋思路不容易出错。
// 递归法
class Solution {
func trimBST(_ root: TreeNode?, _ low: Int, _ high: Int) -> TreeNode? {
guard let root else { return nil }
if root.val > high { return trimBST(root.left, low, high) }
if root.val < low { return trimBST(root.right, low, high) }
root.left = trimBST(root.left, low, high)
root.right = trimBST(root.right, low, high)
return root
}
}
迭代法
就只理解了一下题解吧。
迭代法 其实对于二叉搜索树的性质利用的更多。
先找到 在边界范围内的深度最小的节点 为root
此时root 左子树中需要裁剪的 只剩下 比下界小的case。 所以此时只需要不断往左子树遍历,找到边界外的节点, 然后将该节点的右节点赋给 当前节点的父节点。
此时root 右子树中需要裁剪的 只剩下 比上界大的case。 所以此时只需要不断往右子树遍历,找到边界外的节点, 然后将该节点的左节点赋给 当前节点的父节点。
题目2: 108.将有序数组转换为二叉搜索树
class Solution {
func sortedArrayToBST(_ nums: [Int]) -> TreeNode? {
return sortBSTRecursive(nums, 0, nums.count - 1)
}
func sortBSTRecursive(_ nums: [Int], _ left: Int, _ right: Int) -> TreeNode? {
if left > right { return nil }
let mid = left + (right - left) / 2
let node = TreeNode(nums[mid])
node.left = sortBSTRecursive(nums, left, mid - 1)
node.right = sortBSTRecursive(nums, mid + 1, right)
return node
}
}
题目3: 538.把二叉搜索树转换为累加树
class Solution {
var pre = 0
func convertBST(_ root: TreeNode?) -> TreeNode? {
guard let root else { return nil }
convertBST(root.right)
root.val += pre
pre = root.val
convertBST(root.left)
return root
}
}
class Solution {
var pre = 0
func convertBST(_ root: TreeNode?) -> TreeNode? {
guard let root else { return nil }
var stack: [TreeNode?] = [root]
while !stack.isEmpty {
if let node = stack.removeLast() {
if let left = node.left { stack.append(left) }
stack.append(node)
stack.append(nil)
if let right = node.right { stack.append(right) }
} else {
if let trueNode = stack.removeLast() {
trueNode.val += pre
pre = trueNode.val
}
}
}
return root
}
}