「LeetCode」99-恢复二叉搜索树

97 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情

一.题目:

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

示例 1:

image.png

输入:root = [1,3,null,null,2]
输出:[3,1,null,null,2]
解释:3 不能是 1 的左孩子,因为 3 > 1 。交换 13 使二叉搜索树有效。

示例 2:

image.png

输入:root = [3,1,4,null,null,2]
输出:[2,1,4,null,null,3]
解释:2 不能在 3 的右子树中,因为 2 < 3 。交换 23 使二叉搜索树有效。

提示:

  • 树上节点的数目在范围 [2, 1000] 内
  • -231 <= Node.val <= 231 - 1

二、思路分析:

还是相同的套路,根据题目的提示完成相应的作答。题目中给出二叉搜索树根节点root,里面恰好只有两个节点的值被错误地交换,这句话给了我们两个信息:1.我们只需要找出破坏二叉树搜索的两个节点即可,而且是有且仅有两个2.还告诉了我们一个隐含信息,即我们不用通过新增节点加删除节点的操作完成交换,仅仅是交换两个节点的值即可。所以基本思路为:

  • 我们需要定义两个变量来接收我们需要交换的两个节点的信息。还需要一个变量来存储我们目前遍历的节点的上一位置。
  • 因为是二叉搜索树,它的中序遍历一定是有序的,所以我们借助这一点对二叉搜索树进行遍历,发现不符合的就找到了我们需要找出的节点。这里需要注意的是,第一个不符合结构的一定是最开始找到的那个节点,而node_two则需要我们不断地找寻最后符合条件的。
  • 最后我们进行值的交换即可完成题目的解答。

三、代码:

/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     val: number
 *     left: TreeNode | null
 *     right: TreeNode | null
 *     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.left = (left===undefined ? null : left)
 *         this.right = (right===undefined ? null : right)
 *     }
 * }
 */

/**
 Do not return anything, modify root in-place instead.
 */
function recoverTree(root: TreeNode | null): void {
    let node_one: TreeNode = null;
    let node_two: TreeNode = null;
    //用一个变量标记先前的位置
    let pre: TreeNode = new TreeNode(Number.MIN_SAFE_INTEGER);
    function inorderTraverse(root: TreeNode | null): void{
        //找到交换的两个节点
        if(root === null) return;
        inorderTraverse(root.left);
        //中序遍历位置
        if(root.val < pre.val){
            //找到第一个节点的位置
            if(node_one === null){
                node_one = pre;
            }
            //一直找找到最小的为止
            node_two = root;
        }
        pre = root;
        inorderTraverse(root.right);
    }
    inorderTraverse(root);
    // 进行节点值的交换
    let temp:number = node_one.val;
    node_one.val = node_two.val;
    node_two.val = temp;
}; 

四、总结:

对于二叉搜索树我们需要牢记它的中序遍历一定是有序的,都是遵循左小右大的规则,利用好这一点那么这道题目的思路就很清晰了。

ps:祝大家端午节安康,虽然是迟来的祝福~~~