package com.app.main.LeetCode.tree;
import com.app.main.LeetCode.base.TreeNode;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
*
* 99
*
* hard
*
* 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.
*
* Example 1:
*
* Input: [1,3,null,null,2]
*
* 1
* /
* 3
* \
* 2
*
* Output: [3,1,null,null,2]
*
* 3
* /
* 1
* \
* 2
*
*
*
* Example 2:
* Input: [3,1,4,null,null,2]
*
* 3
* / \
* 1 4
* /
* 2
*
* Output: [2,1,4,null,null,3]
*
* 2
* / \
* 1 4
* /
* 3
*
* Follow up:
* A solution using O(n) space is pretty straight forward.
* Could you devise a constant space solution?
*
*
* Created with IDEA
* author:Dingsheng Huang
* Date:2019/11/11
* Time:下午5:54
*/
public class RecoverBinarySearchTree {
public void recoverTree(TreeNode root) {
List<Integer> list = new ArrayList<>();
TreeNode node1 = null;
TreeNode node2 = null;
TreeNode temp = null;
TreeNode curr = root;
TreeNode pre = null;
Stack<TreeNode> stack = new Stack<>();
while (curr != null || !stack.isEmpty()) {
while (curr != null) {
stack.push(curr);
curr = curr.left;
}
curr = stack.pop();
if (pre != null) {
if (curr.val < pre.val) {
if (node1 != null) {
node2 = curr;
} else {
node1 = pre;
temp = curr;
}
}
pre = curr;
} else {
pre = curr;
}
curr = curr.right;
}
if (node2 == null) {
swap(node1, temp);
} else {
swap(node1, node2);
}
}
private void swap(TreeNode node1, TreeNode node2) {
int temp = node1.val;
node1.val = node2.val;
node2.val = temp;
}
private TreeNode node1 = null;
private TreeNode node2 = null;
private TreeNode temp = null;
private TreeNode pre = null;
public void recoverTree2(TreeNode root) {
inorderTraversal(root);
if (node2 == null) {
swap(temp, node1);
} else {
swap(node1, node2);
}
}
private void inorderTraversal(TreeNode root) {
if (root != null) {
if (root.left != null) {
inorderTraversal(root.left);
}
if (pre == null) {
pre = root;
} else {
if (root.val < pre.val) {
if (node1 == null) {
node1 = pre;
temp = root;
} else {
node2 = root;
}
}
pre = root;
}
if (root.right != null) {
inorderTraversal(root.right);
}
}
}
}