Two nodes of a BST are swapped, correct the BST(恢复两个节点被交换的BST)

Q:

BST的两个节点被交换了,修复它:

Input Tree:10/  \5    8/ \2   20In the above tree, nodes 20 and 8 must be swapped to fix the tree.
Following is the output tree10/  \5    20/ \2   8

Solution:

BST的按中序遍历生成排序数组。所以,一个简单的方法是将输入树的中序遍历结果存储在一个辅助数组中。对辅助数组进行排序。最后,将辅助数组元素插入BST,保持BST的结构不变。该方法的时间复杂度为O(nLogn),所需辅助空间为O(n)。

可以在O(n)时间内解决这个问题,只需对给定的BST进行一次遍历。由于BST的顺序遍历始终是一个排序数组,因此该问题可以简化为一个排序数组的两个元素交换的问题。我们需要处理两种情况:

  • 1.交换的节点在BST的排序顺序不相邻。
For example, Nodes 5 and 25 are swapped in {3 5 7 8 10 15 20 25}. The inorder traversal of the given tree is 3 25 7 8 10 15 20 5

如果仔细观察,在中序遍历中,会发现节点7比之前访问的节点25小。这里保存节点25(上一个节点)的上下文。同样,我们发现节点5比前一个节点20小。这一次,我们保存节点5(当前节点)的上下文。最后,交换两个节点的值。

  • 2.交换的节点在BST的中序遍历中是相邻的。
For example, Nodes 7 and 8 are swapped in {3 5 7 8 10 15 20 25}. The inorder traversal of the given tree is 3 5 8 7 10 15 20 25

与case1不同,此处仅存在一个节点值小于前一个节点值的点。节点7比节点8小。

如何解决?

  • 我们将保持三个指针,first、middle和last。
  • 当找到当前节点(current)值小于前一个节点(previous)值的第一个点时,我们用前一个节点(previous)更新first,middle用当前节点(current)更新。
  • 当我们找到当前节点(current)值小于前一个节点(previous)值的第二个点时,我们用当前节点(current)更新last。在case2中,我们永远找不到第二点。因此,last不会被更新。
  • 处理后,如果last为null,则BST的两个交换节点是相邻的。
    static class _1st_9 {public static void main(String[] args) {_1st_9 handler = new _1st_9();TreeNode root1 = TreeNodeIOUtils.transform("[10,8,20,25,null,15,5,3,7]");handler.printInOrder(root1);System.out.println();
//            handler.correctBST(root1);handler.printInOrder(root1);System.out.println();TreeNode root2 = TreeNodeIOUtils.transform("[10,7,20,5,null,15,25,3,8]");handler.printInOrder(root2);System.out.println();handler.correctBST(root2);handler.printInOrder(root2);System.out.println();}TreeNode first, middle, last;TreeNode prev;public void correctBST(TreeNode root) {correctBSTUtil(root);if (first != null && last != null) {//case1int t = first.val;first.val = last.val;last.val = t;} else if (first != null && middle != null) {//case2 last is nullint t = first.val;first.val = middle.val;middle.val = t;}}public void correctBSTUtil(TreeNode root) {if (root == null) return;correctBSTUtil(root.left);if (prev != null && root.val < prev.val) {if (first == null) {first = prev;middle = root;} else {last = root;}}prev = root;correctBSTUtil(root.right);}public void printInOrder(TreeNode root) {if (root == null) return;printInOrder(root.left);System.out.printf("%d ", root.val);printInOrder(root.right);}}

Reference

  • 恢复二叉搜索树
  • Two nodes of a BST are swapped, correct the BST

Two nodes of a BST are swapped, correct the BST(恢复两个节点被交换的BST)相关推荐

  1. Two nodes of a BST are swapped, correct the BST

    Two nodes of a BST are swapped, correct the BST[转载] Two of the nodes of a Binary Search Tree (BST) a ...

  2. 在BST中查找节点最多的子BST

    给定一棵二叉树,试设计算法在这棵二叉树中寻找节点最多的 BST(Binary Search Tree),如果整棵二叉树本身就是一棵 BST,那么返回整棵树的节点数量.如下是几个例子 解法一:可以从根节 ...

  3. [LeetCode] Inorder Successor in BST 二叉搜索树中的中序后继节点

    Given a binary search tree and a node in it, find the in-order successor of that node in the BST. No ...

  4. 从leetcode1. 两数之和循序渐进(双指针,BST,哈希表)

    leetcode1. 两数之和 1.之前只知道桶排序那种标志数组,所以看到第一眼就想到那个方面去了.但在本题数组里面存储某个数出现的次数对该题是没有意义的,应该存储某个数出现的位置. 2.哈希表是优化 ...

  5. Linux c 二叉搜索树(节点创建、插入BST)

    1 /*2 * File: binary_search_tree.c3 * --------------------------4 * 2017年7月8日5 *6 */7 8 #include < ...

  6. [译文] 初学者应该了解的数据结构: Tree

    原文链接:Tree Data Structures for Beginners 众成翻译地址:初学者应该了解的数据结构: Tree 系列文章,建议不了解树的同学慢慢阅读一下这篇文章,希望对你有所帮助~ ...

  7. 哈夫曼树--顺序结构(建立、编码、解码)

    引子: 这里的哈夫曼树的建立方法和上一篇不一样,是把数据放在数组上面的,而不是链表上面.因此,采用这种方法建立的哈夫曼树对节点的操作上比链式的哈夫曼树简单很多.对于空间问题,如果有m个item,那么需 ...

  8. 每天一道LeetCode-----二叉搜索树的某两个节点被交换位置,修正这个二叉搜索树

    Recover Binary Search Tree 原题链接Recover Binary Search Tree 给定一个二叉搜索树(BST),但是树中有两个节点被交换了,找到这两个节点,将其修正 ...

  9. 第五周 Leetcode 99. Recover Binary Search Tree (HARD)

    Leetcode99 给定一个 二叉搜索树,其中两个节点被交换,写一个程序恢复这颗BST. 只想到了时间复杂度O(n)空间复杂度O(h) h为树高的解法,还没想到空间O(1)的解法. 交换的情况只有两 ...

最新文章

  1. STM32外设之GPIO的推挽输出和开漏输出模式详解
  2. Coursera公开课笔记: 斯坦福大学机器学习第十一课“机器学习系统设计(Machine learning system design)”
  3. 日期相减计算年_函数 | Excel有个“秘密”函数,计算年龄工龄特方便
  4. Mybatis查询传递单个参数和传递多个参数用法
  5. 使用JDBCTemplate实现与Spring结合,方法公用
  6. 【渝粤题库】广东开放大学 经济学基础 形成性考核
  7. 服务器种类繁多 我们网站应该如何选择放置 cnblogs
  8. matlab画滤波器频响应,matlab如何画出“凯泽窗FIR滤波器”的幅频相频响应图
  9. 怎样才能在自动驾驶任务中高效地利用时间轴上的信息进行视频检测?
  10. python存储大量数据_如何在文件中密集地存储大量数据?
  11. TypeError: unhashable type: 'list'
  12. python语言程序设计实践教程实验八答案_Python程序设计实验报告: 实验八 文件...
  13. numpy.reshape
  14. PC协议/微信协议/ipad协议823最新版
  15. IIS-扩展接口ISAPI-Filter分析
  16. 新概念二册 Lesson 29 Taxi!出租汽车! (复习现在完成时)
  17. Eplan P8 2.7 win7/win10 安装(附带资源链接)已更新链接_20210617
  18. sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set的解决方案(linux)
  19. VMware 虚拟机安装 Mac OS X Mountain Lion 苹果系统
  20. Android 标题栏及导航栏设计与实现

热门文章

  1. 2020某医药行业公司面试题
  2. SQL 存储过程 调试
  3. 第二组骆阳洋通信工程三班抓包分析
  4. VS2010下载|官网|Microsoft Visual Studio 2010 (VS2010)旗舰版下载地址
  5. 【主题世界】阿狸对着你卖萌桌面主题
  6. idea git 合并分支
  7. 每日优鲜破发,不影响叮咚买菜逆市上扬
  8. AutoToon_ WACV_2020 自动几何扭曲的脸卡通生成论文阅读笔记
  9. 百度地图4.1_1开发教程(8)为marker加上备注
  10. vivado 如何设置安全状态机模式