问题描述:
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?
分析:因为是BST,所以如果按照中序遍历的方法遍历一遍得到的序列一定是有序的,那么遍历一遍序列就知道了那两个Node是错误的。但是空间复杂度为O(n),并不符合题目要求。
代码如下:468ms
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
List<TreeNode> nodes;
public void recoverTree(TreeNode root) {
nodes = new ArrayList<>();
inorder(root);
int size = nodes.size();
TreeNode first=null,second=null;
for(int i = 0;i<size-1;i++){
TreeNode prev = nodes.get(i);
TreeNode next = nodes.get(i+1);
if(prev.val>next.val){
if(first == null){
first = prev;
second = next;
}
else
second = next;
}
}
int val = first.val;
first.val = second.val;
second.val = val;
}
private void inorder(TreeNode root){
if(root==null)
return;
inorder(root.left);
nodes.add(root);
inorder(root.right);
}
}
在网上看到了一种仿第一种做法的递归版本。只是这里需要维护一个prev节点,该节点就是中序遍历时的前一个节点,然后将prev节点与当前结点比较,如果prev节点大于当前结点,说明存在问题,但并不肯定是这两个节点发生了互换。等全部节点遍历一遍之后,如果有两组发生错误的地方,那么就将第一组的第一个错误点和第二组的第二个错误点交换。如果只有一组发生错误,那就两个节点互换即可。
空间复杂度为O(logN),理论上也不符合要求。但是更进一步的O(1)的算法已经看不懂了,,
代码如下:504ms
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
TreeNode prev = null;
TreeNode first = null;
TreeNode second = null;
public void recoverTree(TreeNode root) {
inOrder(root);
int val = first.val;
first.val = second.val;
second.val = val;
}
private void inOrder(TreeNode root){
if(root==null) {
return;
}
inOrder(root.left);
if(prev!=null && prev.val>root.val)//find the mistake element
{
if(first == null){
first = prev;
second = root;
}else
second = root;
}
prev = root;
inOrder(root.right);
}
}