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?

confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.

OJ's Binary Tree Serialization:

The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.

Here's an example:

   1
/ \
2 3
/
4
\
5

The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".

 
最简单的办法应该是,中序遍历二叉树,将各个结点的值存储在一维向量中,然后进行一次赋值操作。这种方法对任意个数的节点错乱都实用。
 详情见Grangyang的博客

 /**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void recoverTree(TreeNode *root)
{
vector<TreeNode *> treeNode;
vector<int> nodeVal;
inoder(root,treeNode,nodeVal);
sort(nodeVal.begin(),nodeVal.end());
for(int i=;i<treeNode.size();++i)
treeNode[i]->val=nodeVal[i];
} void inoder(TreeNode *root,vector<TreeNode *> &treeNode,vector<int> &nodeVal)
{
if(root==NULL) return;
inoder(root->left,treeNode,nodeVal);
treeNode.push_back(root);
nodeVal.push_back(root->val);
inoder(root->right,treeNode,nodeVal);
}
};

方法二:

用三个指针,w1,w2分别指向第一、二个错误的地方。pre指向当前结点中序遍历中的前一个结点。因有两个结点交换了,所以二叉树的中序遍历中会出现违背有序的情况,一、即中序遍历中相邻的结点被交换,则违背有序的情况出现一次,如132456;二、中序遍历中不相邻的两个结点的值被交换,则出现两次违背有序情况,如153426.针对情况1,pre=3,w1=pre即为3,w2=root,即为2,在后续的遍历中没有违背有序的情况,所以交换w1和w2即可;针对情况2,找到第一个错误点后,w1 !=NULL了,所以,第二个错误点w2=root,第一逆序的前结点,第二逆序的后结点,交换两者即可。

 /**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode *w1,*w2,*pre;
void recoverTree(TreeNode *root)
{
if(root==NULL) return;
w1=w2=pre=NULL;
find(root);
swap(w1->val,w2->val);
}
void find(TreeNode *root)
{
if(root==NULL) return;
find(root->left);
if(pre&&pre->val > root->val)
{
if(w1==NULL) //情况1
{
w1=pre;
w2=root;
}
else //情况2
w2=root;
}
pre=root;
find(root->right);
}
};

方法三

层次遍历中的Mirror方法,修改部分得到。真正的O(1)。

// Now O(1) space complexity
class Solution {
public:
void recoverTree(TreeNode *root) {
TreeNode *first = NULL, *second = NULL, *parent = NULL;
TreeNode *cur, *pre;
cur = root;
while (cur) {
if (!cur->left) {
if (parent && parent->val > cur->val) {
if (!first) first = parent;
second = cur;
}
parent = cur;
cur = cur->right;
} else {
pre = cur->left;
while (pre->right && pre->right != cur) pre = pre->right;
if (!pre->right) {
pre->right = cur;
cur = cur->left;
} else {
pre->right = NULL;
if (parent->val > cur->val) {
if (!first) first = parent;
second = cur;
}
parent = cur;
cur = cur->right;
}
}
}
if (first && second) swap(first->val, second->val);
}
};

[Leetcode] Recover binary search tree 恢复二叉搜索树的更多相关文章

  1. [leetcode]99. Recover Binary Search Tree恢复二叉搜索树

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  2. [LeetCode] Recover Binary Search Tree 复原二叉搜索树

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  3. [LeetCode] 99. Recover Binary Search Tree 复原二叉搜索树

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  4. [LeetCode] Validate Binary Search Tree 验证二叉搜索树

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  5. [leetcode]173. Binary Search Tree Iterator 二叉搜索树迭代器

    Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the ro ...

  6. 099 Recover Binary Search Tree 复原二叉搜索树

    二叉排序树中有两个节点被交换了,要求把树恢复成二叉排序树. 详见:https://leetcode.com/problems/recover-binary-search-tree/submission ...

  7. [CareerCup] 4.5 Validate Binary Search Tree 验证二叉搜索树

    4.5 Implement a function to check if a binary tree is a binary search tree. LeetCode上的原题,请参见我之前的博客Va ...

  8. [LeetCode] Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列

    Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary ...

  9. [LeetCode] Binary Search Tree Iterator 二叉搜索树迭代器

    Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the ro ...

随机推荐

  1. JDK5后的特性整理

    为了大家对JDK有一个全面的了解,下面是我从网上查找并整理了JDK5以后的所有关键新特性!(将会持续更新中) JDK5新特性 自动装箱与拆箱 枚举 静态导入 可变参数(Varargs) 内省(intr ...

  2. ReentrantLock详解

    ReentrantLock概述 ReentrantLock是Lock接口的实现类,可以手动的对某一段进行加锁.ReentrantLock可重入锁,具有可重入性,并且支持可中断锁.其内部对锁的控制有两种 ...

  3. 阅读《大型网站技术架构》,并结合"重大需求征集系统"有感

    今天阅读了<大型网站技术架构:核心原理与案例分析>的第五.六.七章.这三张主要是讲述了一个系统的可用性.伸缩性和可扩展性.而根据文中所讲述的,一个系统的可用性主要是体现在这个系统的系统服务 ...

  4. PHP环境搭建-记录

    转于 http://jingyan.baidu.com/article/fcb5aff797ec41edaa4a71c4.html php5.5 做了大量的更新,在与apache搭配的时候如何选择也很 ...

  5. python2.7入门---异常处理

        python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误.我们可以使用该功能来调试python程序. 异常处理. 断言(Assertions).     首先来看py ...

  6. app:showAsAction 和android:showAsAction

    app:showAsAction 它有三个可选项1.always:总是显示在界面上2.never:不显示在界面上,只让出现在右边的三个点中3.ifRoom:如果有位置才显示,不然就出现在右边的三个点中 ...

  7. git删除本地及远程分支

    1. 删除本地分支: git branch -d branchName 2. 删除远程分支: // 方法一:将删除的本地分支推到远程(要删除的远程分支在本地有映射) git push origin : ...

  8. kill -9 vs killall

    kill Linux中的kill命令用来终止指定的进程(terminate a process)的运行,是Linux下进程管理的常用命令.通常,终止一个前台进程可以使用Ctrl+C键,但是,对于一个后 ...

  9. facebook hash key

    private void printHashKey() { try { PackageInfo info = getPackageManager().getPackageInfo( "xxx ...

  10. 标志寄存器PSW和汇编条件转移指令解释

    标志寄存器PSW 标志寄存器PSW(程序状态字寄存器PSW)   标志寄存器PSW是一个16为的寄存器.它反映了CPU运算的状态特征并且存放某些控制标志.8086使用了16位中的9位,包括6个状态标志 ...