leetcode99-恢复二叉搜索树

原题

二叉搜索树中的两个节点被错误地交换。

请在不改变其结构的情况下,恢复这棵树。

示例 1:

输入: [1,3,null,null,2]

   1
  /
 3
  \
   2

输出: [3,1,null,null,2]

   3
  /
 1
  \
   2

示例 2:

输入: [3,1,4,null,null,2]

  3
 / \
1   4
   /
  2

输出: [2,1,4,null,null,3]

  2
 / \
1   4
   /
  3

进阶:

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

解法

思想

这道题可以使用中序遍历得到一个序列,这个序列的特征是一个有序序列中的两个元素被交换了,那么问题就变成如何找到这两个元素。

看一个例子: 1 2 8 6 7 4 9 ,有序序列中的两个元素被交换了一定会造成一个较大的元素交换到了前面(8),一个较小的元素交换到了后面(4),体现在序列中就是两个异常的情况:6比8小,4比7小。所以可以判断:第一次出现的某节点比前驱节点的值要小的情况,前驱节点就是一个被交换了的节点,而第二次出现的某节点比前驱节点的值要小的情况,该节点就是第二个被交换了的节点。

而还有一种可能是,两个连续的元素被交换了,如:1 3 2 4,出现的情况就是只出现一次某节点比前驱节点的值要小的情况,那么两个被交换的节点就分别是当前节点(2)和其前驱节点(3)。

找到了这两个节点,就可以使用值交换将二叉搜索树恢复回来。

代码

递归中序遍历:

class Solution {
    TreeNode pred;
    TreeNode former,latter;
    public void recoverTree(TreeNode root) {
        recurTree(root);
        int cache = former.val;
        former.val = latter.val;
        latter.val = cache;
    }
    public void recurTree(TreeNode root){
        if(root == null) return;
        recurTree(root.left);
        if(pred == null) pred = root;
        else if(root.val < pred.val) {
            if(former == null) former = pred;
            latter = root;
        }
        pred = root;
        recurTree(root.right);
    }
}

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/leetcode99-%e6%81%a2%e5%a4%8d%e4%ba%8c%e5%8f%89%e6%90%9c%e7%b4%a2%e6%a0%91/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年2月29日
下一篇 2020年3月1日

相关推荐

  • 剑指offer40-最小的k个数

    原题(来源Leetcode) 输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。 示例 1: …

    算法 2020年3月20日
    0390
  • 剑指offer03-数组中重复的数字

    原题(来源Leetcode) 找出数组中重复的数字。 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,…

    算法 2020年3月13日
    0150
  • leetcode78-子集

    原题 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。 说明: 解集不能包含重复的子集。 示例: 输入: nums = [1,2,3] 输出: [ [3…

    算法 2020年5月24日
    0320
  • 力扣杯春季个人赛-剧情触发时间

    这次的个人赛真是让我认清了自己的实力。。两道困难题都没做出?,虽然大家的通过率也不咋地。。 最后排名 我记录一道做出来的题吧,这道题是一道中等题,通过率如下,虽然题目不难,但由于时…

    2020年4月18日
    0480
  • leetcode1103-分糖果II

    原题 排排坐,分糖果。 我们买了一些糖果 candies,打算把它们分给排好队的 n = num_people 个小朋友。 给第一个小朋友 1 颗糖果,第二个小朋友 2 颗,依此类…

    算法 2020年3月5日
    0140
  • leetcode24-两两交换链表中的节点

    原题 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 示例: 给定 1->2->3->…

    算法 2020年1月20日
    0200
  • leetcode287-寻找重复数

    原题 给定一个包含 n + 1 个整数的数组 nums ,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。 …

    2020年1月7日
    0140
  • leetcode203-移除链表元素

    原题 删除链表中等于给定值 val 的所有节点。 示例: 输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2->3->4->5 解法 思想 pre指…

    算法 2019年12月16日
    0360
  • leetcode344-反转字符串

    原题 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组char[]的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间…

    算法 2019年11月18日
    0150
  • leetcode35-搜索插入位置

    原题 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 你可以假设数组中无重复元素。 示例 1: 输入: […

    算法 2020年3月2日
    0130

发表回复

登录后才能评论