您的位置:首页 > 其它

Recover Binary Search Tree

2015-10-17 11:59 323 查看
昨天去freewheel现场笔试,遇到一个编程题,回来才发现是leetcode的一道题目。。。

笔试题目这样描述的:

在一棵Binary Search Tree(BST)中,有二个节点被调换了。请找到这二个被调换的节点,并修复这棵BST,例如:

在树4761352中,节点7和节点2被调换了,将其调整为4261357.

leetcode题目:

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?
错误的做法

昨天简单的考虑了一下,发现会出现二种情况:

1)二个节点离的很远

2)二个节点紧邻

其实没有考虑完全(笔试时间太短了),下面是代码:(二次BST)

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void swap(TreeNode*a,TreeNode*b){
int tmp=a->val;
a->val=b->val;
b->val=tmp;
}
void recoverTree(TreeNode* root) {
queue<TreeNode*> q;
vector<TreeNode*> r;r.clear();
if(root==NULL) return;
q.push(root);
while(!q.empty()){
TreeNode* tmp=q.front();q.pop();
if(tmp->left!=NULL){
if(tmp->left->val<=tmp->val) q.push(tmp->left);
else r.push_back(tmp->left);
}
if(tmp->right!=NULL){
if(tmp->right->val>=tmp->val) q.push(tmp->right);
else r.push_back(tmp->right);
}
}
int n=r.size();
if(n==2){
swap(r[0],r[1]);
}
else if(n==1){
q.push(root);
while(!q.empty()){
TreeNode* tmp=q.front();q.pop();
if(tmp->left!=NULL){
if(tmp->left->val<=tmp->val) q.push(tmp->left);
else {swap(tmp,tmp->left);break;}
}
if(tmp->right!=NULL){
if(tmp->right->val>=tmp->val) q.push(tmp->right);
else {swap(tmp,tmp->right);break;}
}
}
}
}
};
在leetcode没有AC,其中下面的情况就通不过: 3 null 2 null 1

正确的做法:

BST,很容易就让人想到中序遍历,采用中序遍历即可。下面是AC的代码

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void inorder(TreeNode* root){
if(root==NULL) return;
inorder(root->left);
if(prenode!=NULL&&prenode->val>root->val){//不符合排序树的规则了,prenode和root都不符合,首先存prenode
//要是二个临近就只会出现这一次,否则second会被调换。
if(first==NULL) first=prenode;
second=root;
}
prenode=root;
inorder(root->right);
}
void recoverTree(TreeNode* root) {
if(root==NULL) return;
inorder(root);
//找到二个调换元素,swap
int tmp=first->val;
first->val=second->val;
second->val=tmp;
}
private:
TreeNode* prenode; //前一个访问的元素
TreeNode* first; //第一个要被调换的元素
TreeNode* second; //第二个要被调换的元素
};

思路很重要,编程技巧也不能少,多刷题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode