LeetCode Recover Binary Search Tree
2014-12-22 10:47
399 查看
题目
Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
根据上一题的合法性判断,稍作修改,
记录限制元素的位置,可以寻找到不合法的位置,和与之冲突的位置。
根据交换的元素所处的位置,可以分为三种情况:
1、交换的两个位置在一个子树的左右分支上,任何一个元素都不在以另一个元素为根的子树上;
此时交换的这两个位置必然不合法,且是所在分支中不合法位置中深度最小的;
可以首先找到一个不合法的元素。去除以该位置为根的子树后,可找到第二个不合法的元素,交换两者即可。
2、交换的两个位置在一个子树上,一个为该子树的根,另一个在该子树的左子树上;
此时左子树上存在不合法位置,其与发生交换的子树的根冲突;
寻找到第一个不合法位置后,即可找到冲突的位置,即为其中一个交换位置;
另一个元素是第一个交换位置左子树中的最大元素,找到后交换即可;
3、交换的两个位置在一个子树上,一个为该子树的根,另一个在该子树的右子树上;
此时左子树合法,右子树上存在不合法位置,其与发生交换的子树的根冲突;
寻找到第一个不合法位置后,即可找到冲突的位置,即为其中一个交换位置;
另一个元素是第一个交换位置右子树中的最小元素,找到后交换即可;
代码:
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; } } };
相关文章推荐
- ***(leetcode) Recover Binary Search Tree
- LeetCode 之 Recover Binary Search Tree
- leetCode_Recover Binary Search Tree
- 4.6 leetcode -6 recover-binary-search-tree
- LeetCode-Recover Binary Search Tree
- leetcode99 Recover Binary Search Tree java 算法
- [LeetCode]Recover Binary Search Tree
- [LeetCode]Recover Binary Search Tree
- Leetcode: Recover Binary Search Tree
- LeetCode Recover Binary Search Tree
- Java for LeetCode 099 Recover Binary Search Tree
- [LeetCode]Recover Binary Search Tree
- LeetCode---Recover Binary Search Tree
- LeetCode_Recover Binary Search Tree
- LeetCode 99 Recover Binary Search Tree(Python详解及实现)
- leetcode - Recover Binary Search Tree
- 【LeetCode】 Recover Binary Search Tree BST 中序遍历
- LeetCode "Recover Binary Search Tree"
- 【LeetCode】Recover BinarySearch Tree
- LeetCode - Recover Binary Search Tree