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; //第二个要被调换的元素
};
思路很重要,编程技巧也不能少,多刷题。
笔试题目这样描述的:
在一棵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 179 Largest Number
- leetcode 24 Swap Nodes in Pairs
- leetcode 2 Add Two Numbers 方法1
- leetcode 2 Add Two Numbers 方法2
- [LeetCode]47 Permutations II
- [LeetCode]65 Valid Number
- [LeetCode]123 Best Time to Buy and Sell Stock III
- [LeetCode] String Reorder Distance Apart
- [LeetCode] Sliding Window Maximum
- [LeetCode] Find the k-th Smallest Element in the Union of Two Sorted Arrays
- [LeetCode] Determine If Two Rectangles Overlap
- [LeetCode] A Distance Maximizing Problem
- leetcode_linearList
- leetcode_linearList02
- 021-Merge Two Sorted Lists(合并两个排好序的单链表);leetcode
- LeetCode[Day 1] Two Sum 题解
- LeetCode[Day 2] Median of Two Sorted Arrays 题解
- LeetCode[Day 3] Longest Substring Without... 题解
- LeetCode [Day 4] Add Two Numbers 题解
- LeetCode [Day 5] Longest Palindromic Substring 题解