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日

相关推荐

  • 拉帮结派的数据结构-并查集

    本文参考资源: 超超有爱爱-----并查集~~~chen_zan_yu的博客-CSDN博客 概述 并查集通常用作集合的合并。 并查集是一种树形结构,又叫“不相交集合”,保持了一组不…

    2020年2月17日
    0140
  • leetcode503-下一个更大元素II

    原题 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,…

    算法 2020年2月1日
    0100
  • leetcode80-删除排序数组中的重复项II

    原题 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外…

    算法 2020年5月26日
    0140
  • leetcode152-乘积最大子数组

    原题 给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。 示例 1: 输入: [2,3,-2,4] 输出:…

    算法 2020年5月18日
    0130
  • leetcode496-下一个更大元素I

    原题 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每个元素在 nums2 中的下一个比其大的值。 nums…

    算法 2020年1月31日
    0400
  • leetcode232-用栈实现队列

    原题 使用栈实现队列的下列操作: push(x) – 将一个元素放入队列的尾部。 pop() – 从队列首部移除元素。 peek() – 返回队列首部的元素。 empty() – …

    算法 2019年12月13日
    0560
  • 十大排序算法与Java实现

    本文参考资源: https://github.com/iTimeTraveler/SortAlgorithms 十大经典排序算法 - 冰狼爱魔 - 博客园 十大经典排序算法总结(J…

    2020年3月11日
    0800
  • leetcode572-另一个树的子树

    原题 给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树…

    算法 2020年5月8日
    0380
  • leetcode200-岛屿数量

    原题 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水…

    算法 2019年11月24日
    0150
  • leetcode912-排序数组

    原题 给定一个整数数组 nums,将该数组升序排列。 示例 1: 输入: [5,2,3,1] 输出: [1,2,3,5] 示例 2: 输入: [5,1,1,2,0,0] 输出: […

    算法 2020年3月31日
    0350

发表回复

登录后才能评论