LeetCode - Recover Binary Search Tree

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

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Note:
A solution using O( n ) space is pretty straight forward. Could you devise a constant space solution?

这道题是利用BST的规律,inorder traversal的话会返回一个从小到大的list,这时候逆序的就是被交换的。

12345678,交换后 12543678,由于把大数交换到前面,所以第一个逆序的肯定是比它后面的数大的,如果是相邻两个数交换的话,只需要把逆序的数和它后面的数交换就行,如果不是相邻的数的话,第二个逆序肯定是比它前面的数小的,可以看到例子中4,3都比前面的数小,取遇到的最后一个就可以了。

public class Solution {
    private TreeNode previous;
    private TreeNode abnormal1;
    private TreeNode abnormal2;
    
    public void recoverTree(TreeNode root) {
        inorder(root);
        int tmp = abnormal1.val;
        abnormal1.val = abnormal2.val;
        abnormal2.val = tmp;
    }
    public void inorder(TreeNode root){
        if(root==null ) return;
        inorder(root.left);
        if(previous!=null && root.val < previous.val){
            if(abnormal1==null){
                abnormal1 = previous;
                abnormal2 = root;
            }
            else abnormal2 = root;
        }
        previous = root;
        inorder(root.right);
    }
}
这种方法时间复杂度O(n),空间复杂度是递归栈所用的空间O(lgn)

空间复杂度O(1)的解法的解释见这里:http://fisherlei.blogspot.com/2012/12/leetcode-recover-binary-search-tree.html

如何用O(1)空间进行Inorder Tree Traversal:

重点就是一个节点的前一个几点是它左子树的最右节点,于是每次如果有左子树,则找到最右节点,把最右节点的右指针(因为是最右节点,所以一开始肯定为空)指向这个节点,于是当遍历到最右节点时,就可以回到这个节点了。

另外,当发现最右节点的右指针已经指向该节点时,说明左子树已经完全访问过了,于是此时就访问当前节点,然后右子树就可以了。

时间复杂度O(n*lgn),因为此时每个节点都需要去找它左子树的最右节点,which is O(lgn)

    public void recoverTree(TreeNode root) {
        if(root==null) return;
        TreeNode pre = null;
        TreeNode ab1 = null;
        TreeNode ab2 = null;
        TreeNode current = root;
        while(current!=null){
            if(current.left==null){
                if(pre!=null && pre.val>current.val){
                    if(ab1==null){
                        ab1 = pre;
                    }
                    ab2 = current;
                }
                pre = current;
                current = current.right;
            }
            else{
                TreeNode left = current.left;
                while(left.right!=null && left.right!=current){
                    left = left.right;
                }
                if(left.right==current){
                    if(pre!=null && pre.val>current.val){
                        if(ab1==null){
                            ab1 = pre;
                        }
                        ab2 = current;
                    }
                    pre = current;
                    current = current.right;
                    left.right = null;
                }
                else{
                    left.right = current;
                    current = current.left;
                }
                
            }
        }
        int tmp = ab1.val;
        ab1.val = ab2.val;
        ab2.val = tmp;
    }




LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值