您的位置:首页 > 其它

leetcode[99] Recover Binary Search Tree

2014-11-26 23:44 471 查看
题目:二叉树中有两个节点对换了值,恢复他们。

思路:
因为中序遍历是有序的,如果中序遍历后的数组出现乱序,说明就是交换的。从前往后,第一次乱序的第一个,后最后一次乱序的后一个,然后把这两个值对换就好了。

想了个非常挫的办法。

先中序遍历Binary Tree Inorder Traversal,然后在数组中找到两个值,然后再中序遍历找到那两个值,交换一下。虽然AC了,但不忍直视啊。

/**
* 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 inorder(TreeNode *root, vector<int> &perm) // 中序遍历得到数组
{
if (root == NULL) return ;
stack<TreeNode *> sta;

sta.push(root);
TreeNode *p = root -> left, *cen;

while(!sta.empty())
{
if (p)
{
sta.push(p);
p = p -> left;
}
else
{
cen = sta.top();
sta.pop();
perm.push_back(cen -> val);
if (cen -> right)
{
sta.push(cen -> right);
p = cen -> right -> left;
}
}
}
}
void inorderC(TreeNode *root,int val1, int val2) // 中序遍历将对应值修改
{
if (root == NULL) return ;
stack<TreeNode *> sta;

sta.push(root);
TreeNode *p = root -> left, *cen;

while(!sta.empty())
{
if (p)
{
sta.push(p);
p = p -> left;
}
else
{
cen = sta.top();
sta.pop();
if(cen -> val == val1)
cen -> val = val2;
else if(cen -> val == val2)
cen -> val = val1;
if (cen -> right)
{
sta.push(cen -> right);
p = cen -> right -> left;
}
}
}
}
void recoverTree(TreeNode *root)
{
if (!root) return ;
vector<int> perm;
inorder(root, perm);
int val1, val2;
bool flag = true;
for (int i = 0; i < perm.size(); ++i)
{
if (flag && i + 1 < perm.size() && perm[i] > perm[i+1]) // 第一次比后一个大的数
{
val1 = perm[i];
flag = false;
}
if (i - 1 >= 0 && perm[i] < perm[i-1]) // 最后一个比前面小的数
val2 = perm[i];
}
inorderC(root, val1, val2);
}
};


View Code
然后就想到改进,在一次中序遍历中就记录两个节点,然后交换值。

经过优化之后果然好看多了。

/**
* 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)
{
if (!root) return ;
stack<TreeNode *> sta;
vector<int> perm;
TreeNode *p = root, *sw1, *sw2, *pre = NULL;
bool flag1 = false; // 分别表示sw1是否找到
while(p || !sta.empty())
{
while(p)
{
sta.push(p);
p = p -> left;
}
if (!sta.empty())
{
p = sta.top();
// 在//这之间和pre比较
if (pre && !flag1 && pre -> val > p -> val)
{
sw1 = pre; flag1 = true;   // sw1是第一次违法的第一个数
}
if (pre && pre -> val > p -> val)
{
sw2 = p; // sw2是最后一次违法的第二个数
}
//
sta.pop();
pre = p; // 每次加入的对应pre;下一次要加入的时候那么pre就是之前一个了
perm.push_back(p -> val);
p = p -> right;
}
}
swap(sw1->val, sw2->val);
return ;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: