【三次过】691. 恢复二叉搜索树

本文介绍了一种解决二叉搜索树中两个节点值被错误交换的问题的方法。通过中序遍历,找到并交换这两个逆序节点,使树恢复正确顺序。示例展示了算法的应用过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在一棵二叉搜索树中, 只有两个节点是被交换的. 找到这些节点并交换, 如果没有节点被交换就返回原来的树的根节点.

样例

样例1

输入: {4,5,2,1,3}
输出: {4,2,5,1,3}
解释:
给出的二叉搜索树:
    4
   / \
  5   2
 / \
1   3
返回:
    4
   / \
  2   5
 / \
1   3

样例2

输入: {1,2,5,4,3}
输出: {4,2,5,1,3}
解释:
给出的二叉搜索树:
    1
   / \
  2   5
 / \
4   3
返回:
    4
   / \
  2   5
 / \
1   3

解题思路:

使用中序遍历。设置三个节点分别用来标记遍历的前一个节点preNode,第一个逆序节点firstNode,第二个逆序节点secondNode,那么如果寻找逆序的两个节点呢?

考虑中序遍历为1, 5, 3, 4, 2。

如果preNode.val >= root.val,如节点5,3,则preNode节点即为firstNode节点,即节点5为firstNode。

如果firstNode存在 && preNode.val >= root.val,如节点4,2,则root节点即为secondNode节点,即节点2为secondNode。

这样的考虑天然的处理了相邻节点逆序的情况,例如3, 1, 4,firstNode为3,secondNode为1

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

public class Solution {
    /**
     * @param root: the given tree
     * @return: the tree after swapping
     */
    public TreeNode bstSwappedNode(TreeNode root) {
        // write your code here
        inorder(root);
        
        if(firstNode != null && secondNode != null){
            int temp = firstNode.val;
            firstNode.val = secondNode.val;
            secondNode.val = temp;
        }
        
        return root;
    }
    
    TreeNode preNode = new TreeNode(Integer.MIN_VALUE); //root的前一个元素
    TreeNode firstNode = null;  //第一个逆序节点
    TreeNode secondNode = null; //第二个逆序节点
    
    private void inorder(TreeNode root){
        if(root == null)
            return;
            
        inorder(root.left);
        
        if(firstNode == null && preNode.val >= root.val)
            firstNode = preNode;
        
        if(firstNode != null && preNode.val >= root.val)
            secondNode = root;
        
        preNode = root;
            
        inorder(root.right);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值