【Leetcode】99. Recover Binary Search Tree

题目地址:

https://leetcode.com/problems/recover-binary-search-tree/

给定一棵二叉树,交换其恰好两个节点就可以使之成为一棵BST。要求交换那两个节点然后返回新树树根,不允许改变树的结构。要求空间 O ( 1 ) O(1) O(1)

可以采用Morris中序遍历。交换两个节点之后,中序遍历的序列中可能会有一次下降(交换相邻位置数的情况),也可能会有两次下降(交换不相邻位置数的情况),设要交换的两个节点分别为 p p p q q q,那么先找到第一次下降的数对中第一个数,暂时将第二个数存入 q q q,如果发现第二次下降,则将第二次下降的数对中第二个数存入 q q q,最后只需要交换 p p p q q q即可。代码如下:

public class Solution {
    public void recoverTree(TreeNode root) {
    	// prev记录中序遍历的前驱
        TreeNode cur = root, prev = null, p = null, q = null;
        while (cur != null) {
            TreeNode left = cur.left;
            if (left == null) {
                if (prev != null && prev.val > cur.val) {
                    if (p == null) {
                        p = prev;
                    }
                    
                    q = cur;
                }
                
                prev = cur;
                cur = cur.right;
            } else {
                while (left.right != null && left.right != cur) {
                    left = left.right;
                }
                
                if (left.right == null) {
                    left.right = cur;
                    cur = cur.left;
                } else {
                    left.right = null;
                    if (prev != null && prev.val > cur.val) {
                        if (p == null) {
                            p = prev;
                        }
                        
                        q = cur;
                    }
                    
                    prev = cur;
                    cur = cur.right;
                }
            }
        }
        
        swap(p, q);
    }
    
    void swap(TreeNode p, TreeNode q) {
        int tmp = p.val;
        p.val = q.val;
        q.val = tmp;
    }
}

class TreeNode {
    int val;
    TreeNode left, right;
    
    public TreeNode(int val) {
        this.val = val;
    }
}

时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值