题目1: 235. 二叉搜索树的最近公共祖先
思路: 粗看了下题解,本题想到最后的答案,需要建立在如何巧妙利用二叉搜索树的特性上。 从上而下,遍历遇到当前节点的val 在 [p, q] 区间内,则这个节点即为 目标节点。
对于这个推论,我最直观想到可能得bad case 如下,既我从上往下找到pq的祖先节点,但他不是最近的。
结果呢,图画出来,就发现这种case也不存在。 比如这个node1,满足祖先节点,但不是最近的,那他一定不在[p, q]区间内。
自己写的版本 不够高效,缺少的利用二叉搜索树的有序 调整递归方向的操作。
class Solution {
func lowestCommonAncestor(_ root: TreeNode?, _ p: TreeNode?, _ q: TreeNode?) -> TreeNode? {
guard let root, let p, let q else { return nil }
if (p.val >= root.val && q.val <= root.val) || (q.val >= root.val && p.val <= root.val) {
return root
}
if let node = lowestCommonAncestor(root.left, p, q) {
return node
}
if let node = lowestCommonAncestor(root.right, p, q) {
return node
}
return nil
}
}
// 看完题解后 优化
class Solution {
func lowestCommonAncestor(_ root: TreeNode?, _ p: TreeNode?, _ q: TreeNode?) -> TreeNode? {
guard let root, let p, let q else { return nil }
if root.val > q.val, root.val > p.val,
let node = lowestCommonAncestor(root.left, p, q) {
return node
}
if root.val < q.val, root.val < p.val,
let node = lowestCommonAncestor(root.right, p, q) {
return node
}
return root
}
}
题目2: 701.二叉搜索树中的插入操作
思路有点固化,没有想到。
class Solution {
func insertIntoBST(_ root: TreeNode?, _ val: Int) -> TreeNode? {
guard let root else { return TreeNode(val) }
if val > root.val { root.right = insertIntoBST(root.right, val) }
if val < root.val { root.left = insertIntoBST(root.left, val) }
return root
}
}
// 迭代法
class Solution {
func insertIntoBST(_ root: TreeNode?, _ val: Int) -> TreeNode? {
guard let root else { return TreeNode(val) }
var cur: TreeNode? = root
var parent: TreeNode?
while let node = cur {
parent = node
if node.val > val { cur = node.left }
if node.val < val { cur = node.right }
}
if let parent {
if parent.val > val {
parent.left = TreeNode(val)
} else {
parent.right = TreeNode(val)
}
}
return root
}
}
题目3:450.删除二叉搜索树中的节点
// 递归法
class Solution {
func deleteNode(_ root: TreeNode?, _ key: Int) -> TreeNode? {
guard let root else { return nil }
if root.val == key {
if let left = root.left, let right = root.right {
var cur = right
while cur.left != nil { cur = cur.left ?? TreeNode() }
cur.left = left
return right
}
else if root.right == nil { return root.left }
else if root.left == nil { return root.right }
else { return nil }
}
if key < root.val { root.left = deleteNode(root.left, key) }
if key > root.val { root.right = deleteNode(root.right, key) }
return root
}
}
class Solution {
func deleteNode(_ root: TreeNode?, _ key: Int) -> TreeNode? {
guard let root else { return nil }
var cur: TreeNode? = root
var pre: TreeNode?
while cur != nil {
guard let node = cur else { break }
if key == node.val { break }
pre = node
if key > node.val { cur = node.right }
if key < node.val { cur = node.left }
}
guard let pre else { return removeOneNode(root) }
if let left = pre.left, left.val == cur?.val ?? 0 {
pre.left = removeOneNode(cur)
}
if let right = pre.right, right.val == cur?.val ?? 0 {
pre.right = removeOneNode(cur)
}
return root
}
func removeOneNode(_ root: TreeNode?) -> TreeNode? {
guard let root else { return nil }
if root.left == nil { return root.right }
if root.right == nil { return root.left }
if let left = root.left, let right = root.right {
var cur = right
while cur.left != nil {
cur = cur.left ?? TreeNode()
}
cur.left = left
return right
}
return nil
}
}