leetcode--Recover Binary Search Tree*
1.题目描述
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?
2.解法分析
对有异常的BST进行pre-order的遍历,遍历过程中第一次发现相邻元素的逆序,即前一个元素值比后一个节点的元素值大,那么前一个节点是被交换的节点中的其中一个,记为sw1,继续遍历,找到第一个比sw1中元素值大的节点sw2,如果找到,sw1和sw2,交换它们的元素值即可。细节参考代码。
/**
* 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) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
vector<TreeNode *> v;TreeNode * curTN=root;TreeNode *prevTN=NULL;TreeNode *sw1=NULL;TreeNode *sw2=NULL;while(!v.empty()||curTN)
{while(curTN)
{v.push_back(curTN);curTN=curTN->left;}if(!v.empty())
{curTN =v.back();v.pop_back();if(!sw1){
if(!prevTN){
prevTN=curTN;}else
{if(curTN->val<prevTN->val){
sw1=prevTN;}prevTN =curTN;}}else
{if(curTN->val>sw1->val){sw2=prevTN;break;}else prevTN=curTN;
}curTN = curTN->right;}}if(!sw1)return; //未找到异常交换if(!sw2)sw2=prevTN;//最大的一个节点被交换int temp=sw1->val;
sw1->val=sw2->val;sw2->val=temp;}};
另外题目说不用O(N)的空间复杂度会有加分,在discuss里面找了一个,没仔细看,思路大概跟我的一样,但是就是记录路径可能用了不同的办法,貌似叫做morris traversal,代码如下,做个记录,之后再分析(今天写了一篇文章,详细介绍了Morris Traveral):
/**
* 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 *h) {
TreeNode *f1, *f2;bool found = false;
TreeNode *pre, *par = 0; // previous AND parent
while(h) { // Morris Traversalif(h->left == 0) {
if(par && par->val > h->val) { // inorder previous is: parif(!found) {
f1 = par;found = true;}f2 = h;}par = h;h = h->right;continue;
}pre = h->left;while(pre->right != 0 && pre->right != h)
pre = pre->right;if(pre->right == 0) {
pre->right = h;h = h->left;} else {
pre->right = 0;if(pre->val > h->val) { // inorder previous is: preif(!found) {
f1 = pre;found =true;}f2 = h;}par = h;h = h->right;}}if(found)
swap(f1->val, f2->val);}};