题目
二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
进阶:
- 使用 O(n) 空间复杂度的解法很容易实现。
- 你能想出一个只使用常数空间的解决方案吗?
解答
本题需要找到两个需要交换的结点使得二叉搜索树结构恢复。
思路:如若按照中序遍历的序列来讲,问题就转化为找中序遍历结果的两个逆序对。
中序遍历算法的复杂度如下:
- 递归:O(n) 时间,O(n) 空间。
- 栈:O(n) 时间,O(n) 空间。
- Mirros 算法:O(n) 时间,O(1) 空间。
遍历方式一:递归
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
TreeNode firstNode = null;
TreeNode secondNode = null;
TreeNode pre = new TreeNode(Integer.MIN_VALUE);
public void recoverTree(TreeNode root) {
inOrder(root);
int temp = firstNode.val;
firstNode.val = secondNode.val;
secondNode.val = temp;
}
private void inOrder(TreeNode node) {
if (node == null) return;
inOrder(node.left);
if(firstNode == null && pre.val > node.val) firstNode = pre;
if(firstNode != null && pre.val > node.val) secondNode = node;
pre = node;
inOrder(node.right);
}
}
结果
遍历方式二:栈
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public void recoverTree(TreeNode root) {
TreeNode firstNode = null;
TreeNode secondNode = null;
LinkedList<TreeNode> stack = new LinkedList<>();
TreeNode pre = new TreeNode(Integer.MIN_VALUE);
TreeNode cur = root;
while(cur != null || !stack.isEmpty()) {
while(cur != null) {
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
if(firstNode == null && pre.val > cur.val) firstNode = pre;
if(firstNode != null && pre.val > cur.val) secondNode = cur;
pre = cur;
cur = cur.right;
}
int temp = firstNode.val;
firstNode.val = secondNode.val;
secondNode.val = temp;
}
}
结果
遍历方式三:Mirros算法
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public void recoverTree(TreeNode root) {
TreeNode firstNode = null;
TreeNode secondNode = null;
TreeNode cur = root;
TreeNode last = null;
TreeNode pre = new TreeNode(Integer.MIN_VALUE);
while(cur != null) {
if(cur.left == null) {
if(firstNode == null && pre.val > cur.val) firstNode = pre;
if(firstNode != null && pre.val > cur.val) secondNode = cur;
pre = cur;
cur = cur.right;
} else {
last = cur.left;
while(last.right != null && last.right != cur) {
last = last.right;
}
if(last.right == null) {
last.right = cur;
cur = cur.left;
}
if(last.right == cur) {
last.right = null;
if(firstNode == null && pre.val > cur.val) firstNode = pre;
if(firstNode != null && pre.val > cur.val) secondNode = cur;
pre = cur;
cur = cur.right;
}
}
}
int temp = firstNode.val;
firstNode.val = secondNode.val;
secondNode.val = temp;
}
}