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 \ 5The above binary tree is serialized as
"{1,2,3,#,#,4,#,#,5}"
.搞清楚了规律就容易实现了,中序遍历寻找逆序情况,调换的第一个元素,永远是第一个逆序的第一个元素,而调换的第二个元素如果只有一次逆序,则是那一次的后一个,如果有两次逆序则是第二次的后一个。算法只需要一次中序遍历,所以时间复杂度是O(n),空间是栈大小O(logn)。
#include<iostream> #include<new> using namespace std; //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 *first=NULL; TreeNode *second=NULL; TreeNode *pre=NULL; void recoverTree(TreeNode *root) { recoverInorder(root); swap(first->val,second->val); } void recoverInorder(TreeNode *root) { if(root) { recoverInorder(root->left); if(pre&&pre->val>root->val) { if(first==NULL) { first=pre; second=root; } else second=root; } pre=root; recoverInorder(root->right); } } void createTree(TreeNode *&root) { int arr[10]= {5,9,7,8,6,10,4,2,1,3}; int i; for(i=0; i<10; i++) insert(root,arr[i]); } void insert(TreeNode *&root,int key) { TreeNode *tmp=new TreeNode(key); if(root==NULL) { root=tmp; } else if(key<root->val) insert(root->left,key); else insert(root->right,key); } void inorder(TreeNode *root) { if(root) { inorder(root->left); cout<<root->val<<" "; inorder(root->right); } } }; int main() { Solution s; TreeNode *root=NULL; s.createTree(root); s.inorder(root); cout<<endl; swap(root->left->val,root->right->val); s.inorder(root); cout<<endl; s.recoverTree(root); s.inorder(root); }
运行结果: