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?
二叉查找樹中有兩個節點被調換了,要求在不改變樹的結構的情況下恢復原狀。
思路:找到第一個比它的直接後繼結點中的值更大的結點A,然後向後找到【第一個】比A中的值大的結點B,然後將A的值和B的直接前驅中的值交換,返回。
1、空間複雜度O(n)的做法
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<TreeNode*> com;
void Traverse(TreeNode *root)
{
if (!root) return;
Traverse(root->left);
com.push_back(root);
Traverse(root->right);
}
void recoverTree(TreeNode *root) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
com.clear();
Traverse(root);
TreeNode *itema=NULL,*itemb=NULL;
for (size_t i=0; i<com.size(); ++i)
{
if (!itema && i+1 < com.size() && com[i]->val > com[i+1]->val)
{
itema = com[i];
while (++i < com.size())
{
if (com[i] > itema->val)
break;
}
if (i == com.size())
itemb = com.back();
else
itemb = com[i-1];
int temp = itema->val;
itema->val = itemb->val;
itemb->val = temp;
break;
}
}
}
};
2 、空間複雜度O(1)的做法
/**
* 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 *prev;
TreeNode *itema, *itemb;
void traverse(TreeNode *root)
{
if(!root) return;
traverse(root->left);
if(prev)
{
if(itema && root->val > itema->val)
itemb = prev;
if(!itema && prev->val > root->val)
itema = prev;
// pay attention!
if (itema && itemb)
return;
}
prev = root;
traverse(root->right);
}
void recoverTree(TreeNode *root)
{
prev = itema = itemb = NULL;
traverse(root);
if (itema && !itemb)
itemb = prev;
if (itema && itemb)
{
int temp = itema->val;
itema->val = itemb->val;
itemb->val = temp;
}
}
};