Leetcode Recover Binary Search Tree,本题的关键是“如何使用O(1)
的空间遍历树”和“找出两个被swap的节点”。
O(1)
的空间遍历树这里主要需要使用一个数据节构Threaded binary tree,借助于Threaded binary tree可以很快的实现遍历。此外,使用in-order
遍历搜索二叉树,正好是以升序遍历整个数据。
由上一部分可知,我们以升序的方式遍历数据,如果有两个节点被交换,那么可以很简单的找到,第一个遇到的被交换的结点一定是较大的一个,所以通过相关判断可以很快的找出两个被交换的节点。
相关代码如下:
#include
#include
using namespace std;
/**
* We use the Threaded binary tree to solve this problem.
* Threaded binary tree can scan the binary tree in O(1) space.
* We using Threaded binary tree trave the origin binary search tree with
* in-order, so we trave the tree in a increase sequence.
* There are two element are swaped, so in this order, the first one encounted
* of the two is the lagger one, and the other one is the smaller. We can
* get the two by detect the trend of the element
*/
// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
void recoverTree(TreeNode* root) {
if (!root) {
return;
}
TreeNode* cur = root;
TreeNode* cur_pre {}; // Record the element preceded current element
TreeNode* pre;
TreeNode* first {}; // The bigger swapped node
TreeNode* second {}; // The smaller swapped node
while (cur) {
if (!cur->left) {
/**
* There is not node less than this one
*/
// If not find the bigger one, we first search it
if (!first && cur_pre && cur_pre->val > cur->val) {
first = cur_pre;
}
// If the bigger is found, we get the smaller
if (first && cur_pre && cur_pre->val > cur->val) {
second = cur;
}
cur_pre = cur;
cur = cur->right;
} else {
/**
* First scan the node which less than current
*/
pre = cur->left;
while (pre->right && pre->right != cur) {
pre = pre->right;
}
if (!pre->right) {
// joint the sequence
pre->right = cur;
cur = cur->left;
} else {
// disjoint the sequence and check the value
pre->right = nullptr;
if (!first && cur_pre && cur_pre->val > cur->val) {
first = cur_pre;
}
if (first && cur_pre && cur_pre->val > cur->val) {
second = cur;
}
cur_pre = cur;
cur = cur->right;
}
}
}
if (first && second) {
swap(first->val, second->val);
}
}
bool judge(TreeNode* cur, TreeNode* cur_pre) {
if (cur->right && cur->val > cur->right->val) {
return true;
}
if (cur_pre && cur_pre->val > cur->val) {
return true;
}
return false;
}
};
int main(/*int argc, char* argv[]*/) {
Solution so;
TreeNode* a = new TreeNode(2);
a->right = new TreeNode(3);
a->right->left = new TreeNode(1);
so.recoverTree(a);
cout << a->val << endl;
return 0;
}