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?

分析

O(logn)空间的解法是,中序递归遍历,用两个指针存放在遍历过程中碰到的两处逆向的位置。

本题要求O(1)空间,只能用Morris中序遍历。

中序遍历,递归方式

  1. // Recover Binary Search Tree
  2. // 中序遍历,递归
  3. // 时间复杂度O(n),空间复杂度O(logn)
  4. // 本代码仅仅是为了帮助理解题目
  5. public class Solution {
  6. private TreeNode p1 = null;
  7. private TreeNode p2 = null;
  8. private TreeNode prev = null;
  9. public void recoverTree(TreeNode root) {
  10. inOrder( root);
  11. // swap
  12. int tmp = p1.val;
  13. p1.val = p2.val;
  14. p2.val = tmp;
  15. }
  16. private void inOrder(TreeNode root) {
  17. if ( root == null ) return;
  18. if ( root.left != null ) inOrder(root.left);
  19. if ( prev != null && root.val < prev.val ) {
  20. if ( p1 == null) {
  21. p1 = prev;
  22. p2 = root;
  23. } else {
  24. p2 = root;
  25. }
  26. }
  27. prev = root;
  28. if ( root.right != null ) inOrder(root.right);
  29. }
  30. }

Morris中序遍历

  1. // Recover Binary Search Tree
  2. // Morris中序遍历,时间复杂度O(n),空间复杂度O(1)
  3. public class Solution {
  4. public void recoverTree(TreeNode root) {
  5. TreeNode[] broken = new TreeNode[2];
  6. TreeNode prev = null;
  7. TreeNode cur = root;
  8. while (cur != null) {
  9. if (cur.left == null) {
  10. detect(broken, prev, cur);
  11. prev = cur;
  12. cur = cur.right;
  13. } else {
  14. TreeNode node = cur.left;
  15. while (node.right != null && node.right != cur)
  16. node = node.right;
  17. if (node.right == null) {
  18. node.right = cur;
  19. //prev = cur; 不能有这句!因为cur还没有被访问
  20. cur = cur.left;
  21. } else {
  22. detect(broken, prev, cur);
  23. node.right = null;
  24. prev = cur;
  25. cur = cur.right;
  26. }
  27. }
  28. }
  29. // swap
  30. int tmp = broken[0].val;
  31. broken[0].val = broken[1].val;
  32. broken[1].val = tmp;
  33. }
  34. void detect(TreeNode[] broken, TreeNode prev,
  35. TreeNode current) {
  36. if (prev != null && prev.val > current.val) {
  37. if (broken[0] == null) {
  38. broken[0] = prev;
  39. } //不能用else,例如 {0,1},会导致最后 swap时second为nullptr,
  40. //会 Runtime Error
  41. broken[1] = current;
  42. }
  43. }
  44. }

相关题目

原文: https://soulmachine.gitbooks.io/algorithm-essentials/content/java/binary-tree/traversal/recover-binary-search-tree.html