LeetCode Recover Binary Search Tree

来源:互联网 发布:淘宝被盗后果 编辑:程序博客网 时间:2024/06/06 20:00

题目

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

 

 

根据上一题的合法性判断,稍作修改,

记录限制元素的位置,可以寻找到不合法的位置,和与之冲突的位置。

 

 

根据交换的元素所处的位置,可以分为三种情况:

1、交换的两个位置在一个子树的左右分支上,任何一个元素都不在以另一个元素为根的子树上;

此时交换的这两个位置必然不合法,且是所在分支中不合法位置中深度最小的;

可以首先找到一个不合法的元素。去除以该位置为根的子树后,可找到第二个不合法的元素,交换两者即可。

2、交换的两个位置在一个子树上,一个为该子树的根,另一个在该子树的左子树上;

此时左子树上存在不合法位置,其与发生交换的子树的根冲突;

寻找到第一个不合法位置后,即可找到冲突的位置,即为其中一个交换位置;

另一个元素是第一个交换位置左子树中的最大元素,找到后交换即可;

3、交换的两个位置在一个子树上,一个为该子树的根,另一个在该子树的右子树上;

此时左子树合法,右子树上存在不合法位置,其与发生交换的子树的根冲突;

寻找到第一个不合法位置后,即可找到冲突的位置,即为其中一个交换位置;

另一个元素是第一个交换位置右子树中的最小元素,找到后交换即可;

 

代码:

/** * Definition for binary tree * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:struct dp//探测用点{TreeNode *tn,*min,*max;//当前位置,当前位置的下限所在位置,上限所在位置dp(TreeNode *t=NULL,TreeNode *mi=NULL,TreeNode *ma=NULL):tn(t),min(mi),max(ma){}};dp test(vector<dp> &sdp)//dfs寻找不符合条件的点{int min,max;dp dp1;while(!sdp.empty())//dfs{dp1=sdp.back();sdp.pop_back();min=dp1.min==NULL?INT_MIN:dp1.min->val;//求限制的值max=dp1.max==NULL?INT_MAX:dp1.max->val;if(dp1.tn==NULL)continue;if(dp1.tn->val<=min||dp1.tn->val>=max)//不符合要求则返回相应信息{return dp1;break;}sdp.push_back(dp(dp1.tn->right,dp1.tn->val>min?dp1.tn:dp1.min,dp1.max));//更新限制sdp.push_back(dp(dp1.tn->left,dp1.min,dp1.tn->val<max?dp1.tn:dp1.max));}return dp();}TreeNode* find_min(TreeNode *root,TreeNode *min)//寻找分支中最小值的点{if(root!=NULL){if(root->val<min->val)min=root;min=find_min(root->left,min);min=find_min(root->right,min);}return min;}TreeNode* find_max(TreeNode *root,TreeNode *max)//寻找分支中最大值的点{if(root!=NULL){if(root->val>max->val)max=root;max=find_max(root->left,max);max=find_max(root->right,max);}return max;}    void recoverTree(TreeNode *root) {dp first,second;//记录不符合要求的点的位置TreeNode *tp;vector<dp> sdp;//dfs用栈sdp.push_back(dp(root));//压入根first=test(sdp);//探测第一个if(first.tn==NULL)return;second=test(sdp);//探测非第一个外的分支,找第二个if(second.tn!=NULL)//存在,说明交换的位置在一个子树树的左右子树上,交换回来即可{cout<<"c1";swap(first.tn->val,second.tn->val);return;}sdp.clear();//否则,说明交换的位置在一个子树上,其中一个交换位置是该子树的根int min=first.min==NULL?INT_MIN:first.min->val;int max=first.max==NULL?INT_MAX:first.max->val;if(first.tn->val<min)//超下界,说明另一个交换的位置在分支的左子树上,寻找分支最小的位置,和冲突位置交换{tp=find_min(first.tn,first.tn);swap(first.min->val,tp->val);return;}if(first.tn->val>max)//超上界,说明另一个交换的位置在分支的右子树上,寻找分支最大的位置,和冲突位置交换{tp=find_max(first.tn,first.tn);swap(first.max->val,tp->val);return;}    }};


 

 

 

 

 

0 0
原创粉丝点击