[算法]恢复二叉搜索树

61 阅读1分钟

0x00 题目

给你 二叉搜索树 的根节点 root
该树中的 两个 节点被错误地交换
请在不改变其结构的情况下,恢复这棵树

进阶:使用 O(n) 空间复杂度的解法很容易实现。
你能想出一个只使用 常数 空间的解决方案吗?


0x01 思路

二叉搜索树 中序遍历 是一个 升序 数组
2 个节点被错误地交换了,那么会存在以下特征:
正确顺序:1,2,3,4,5,6
错误顺序:1,2,5,4,3,6
2 个地方, 一个数比 一个数【小】

或者
错误顺序:1,2,43,5,6
1 个地方, 一个数比 一个数【小】

记录这 2 个节点,然后交换它们的值即可
因为不知道是有 1 个,还是 2 个地方,所以要遍历全部节点
node2 会在符合条件的地方更新


0x02 解法

语言:Swift

树节点:TreeNode

public class TreeNode {
    public var val: Int
    public var left: TreeNode?
    public var right: TreeNode?
    public init() { self.val = 0; self.left = nil; self.right = nil; }
    public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
    public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
        self.val = val
        self.left = left
        self.right = right
    }
}

解法:

func recoverTree(_ root: TreeNode?) {
    var pre: TreeNode?
    var node1: TreeNode?
    var node2: TreeNode?
    
    func dfs(_ root: TreeNode?) {
        guard let root = root else {
            return
        }
        
        // 前序遍历位置
        dfs(root.left)
        
        // 中序遍历位置
        if pre == nil {
            pre = root
        }else if root.val > pre!.val {
            pre = root
        }else{
            // 记录节点
            if node1 == nil {
                node1 = pre
            }
            node2 = root
        }
        
        dfs(root.right)
        // 后序遍历位置
    }
    
    dfs(root)
    
    // 进行交换
    let tmp = node2!.val
    node2?.val = node1!.val
    node1?.val = tmp
}

0x03 我的小作品

欢迎体验我的作品之一:小笔记-XNote
让笔记一步到位!
App Store 搜索即可~