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);
}
};

最新文章

  1. SQL Server架构 -- 数据库文件和文件组
  2. shell获取文件最后100行,开头100行,指定开始行和结束行的内容
  3. github上readme.md 格式
  4. pip的相关操作
  5. Oracle EBS APIs
  6. Deep learning:四十四(Pylearn2中的Quick-start例子)
  7. scala 学习笔记(03) 参数缺省值、不定个数参数、类的属性(Property)、泛型初步
  8. nmake geos
  9. Hbase之Exception
  10. K2认证考试,为竞争力加分
  11. linux驱动分离分层的概念
  12. 华为2015 简单 字典输入法 java
  13. Android中的自定义属性的实现
  14. leetcode Permutation
  15. CSDN书籍下载
  16. Android Paint画笔及Color .
  17. virtual box ubuntu 主机和虚拟机实现互相复制粘贴
  18. zTree理解和简单Demo(转)
  19. ubuntu 安装 evpp
  20. ubuntu14.04 mysql数据库允许远程访问设置

热门文章

  1. tp5 数据库信息导出到excel(带图片)
  2. UVA - 12230
  3. Java——Random类随机整数---18.10.11
  4. MVC4+EF 列表数据不能绑定
  5. 【娱乐向】制作Chrome天气预报扩展程序
  6. 10-mongodb启动错误
  7. Hibernate-ORM:09.Hibernate中的getCurrentSession()
  8. mysql ON DUPLICATE KEY UPDATE、REPLACE INTO
  9. Java日志(一):log4j与.properties配置文件
  10. AV Foundation 实现文字转语音