您的位置:首页 > 其它

Leetcode中几道二叉树题 I

2014-05-25 19:24 253 查看
一、二叉搜索树 (Binary Search Tree)

题目一:Recover Binary Search Tree

Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure.

思路:利用搜查树的特性——中序遍历的结果是有序的,可以找打两个交换值,然后再重新遍历恢复原值。

class Solution {
private:
int first, second, last;
public:
void recoverTree(TreeNode *root) {
if(root==NULL) return;
first=1<<12;
second=1<<12;
last=-1<<12;
findSwapNodes(root);
recoverSwapNodes(root);
}

void recoverSwapNodes(TreeNode *root){
if(root==NULL) return;
recoverSwapNodes(root->left);
if(first==root->val){
root->val=second;
}
else if(second==root->val){
root->val=first;
}
recoverSwapNodes(root->right);
}

void findSwapNodes(TreeNode *root){
if(root==NULL) return;
findSwapNodes(root->left);
if(root->val<last){
if(second==1<<12){
second=last;
first=root->val;
}
if(root->val<first) first=root->val;
}
last=root->val;
findSwapNodes(root->right);
}
};


题目二:Convert Sorted List to Binary Search Tree

Given a singly linked list where elements are sorted in ascending order, convert it to height balanced BST

思路:将链表均分成两半,各递归构造根节点的左右子树。

class Solution {
public:
TreeNode *sortedListToBST(ListNode *head) {
if(head==NULL) return NULL;
if(head->next==NULL) return new TreeNode(head->val);

TreeNode *newhead=NULL;
ListNode *p1, *p2;
p2=head;
p1=head->next; //使得p2在中间位置的前二位
while(p1 && p1->next && p1->next->next){
p1=p1->next->next;
p2=p2->next;
}
p1=p2->next;
p2->next=NULL;
newhead=new TreeNode(p1->val);
if(p1->next) newhead->right=sortedListToBST(p1->next);
newhead->left=sortedListToBST(head);
return newhead;
}
};


题目三:Convert Sorted Array to Binary Search Tree

Given an array where elements are sorted in ascending order, convert it to a height balanced BST

思路:思路同上!注意二分递归是注意边界条件。

class Solution {
public:
TreeNode *sortedArrayToBST(vector<int> &num) {
if(num.size()==0) return NULL;
return sortedArrayToBST(num, 0, num.size()-1);
}

TreeNode *sortedArrayToBST(vector<int>& num, int start, int end){
TreeNode *head=NULL;
if(start<=end){
int mid=(start+end)/2;
head=new TreeNode(num[mid]);
if(start<mid){  //边界条件
head->left=sortedArrayToBST(num, start, mid-1);
}
if(mid<end){
head->right=sortedArrayToBST(num, mid+1, end);
}
}
return head;
}
};


题目四:Unique Binary Search Trees

Given n, how many structurally unique BST's (binary search trees) that store values 1...n?

思路:这道题用BF方法会超时。其实这是一道组合问题。按照数学的方式就能求得解。

class Solution {
public:
int numTrees(int n) {
if(n<=0) return 0;

vector<int> result;
result.push_back(1); //n=0 退化的情况
result.push_back(1); //n=1

for(int k=2;k<=n;k++) //n>1
{
int sum=0;
for(int i=1;i<=k;i++)
{
sum+=(result[i-1]*result[k-i]);
}

result.push_back(sum);
}

return result
;
}
};


题目五:Unique Binary Search Trees II

Given n, generate all structurally unique BST's (binary search trees) that store values 1..n.

思路:不同于上面那道题,这里必须用枚举的方法。二分递归。这道题最开始我一直被一个weird problem缠住,我也不能理解,为啥出错。下面先贴出错误代码。

class Solution {
public:
vector<TreeNode*> generateTrees(int low, int high){
vector<TreeNode*> res;
if(low<=high){
TreeNode *root;
vector<TreeNode*> left, right;
for(int i=low; i<=high; i++){
root=new TreeNode(i);
left.clear();
right.clear();
left=generateTrees(low, i-1);
right=generateTrees(i+1, high);
if(left.size() && right.size()){
for(int j=0; j<left.size(); j++)
for(int k=0; k<right.size(); k++){
root->left=left[j];
root->right=right[k];
res.push_back(root);
}
}
else if(left.size() || right.size()){
for(int j=0; j<left.size(); j++){
root->left=left[j];
res.push_back(root);
}
for(int j=0; j<right.size(); j++){
root->right=right[j];
res.push_back(root);
}
}
else res.push_back(root);
}
}
return res;
}

vector<TreeNode *> generateTrees(int n) {
vector<TreeNode*> res;
if(n==0){
res.push_back(NULL);
return res;
}
return generateTrees(1, n);
}
};
错误的原因:root的左右孩子节点被覆盖掉了。虽然以为root加入res以后就没啥事了,root本身的值没啥事,但是后面的操作改变了root左右孩子节点的值。还是对指针理解不够深刻!

class Solution {
public:
vector<TreeNode*> generateTrees(int low, int high){
vector<TreeNode*> res;
if(low>high){
res.push_back(NULL);   //添加叶子节点也是十分必要的呀!
return res;
}
else{
for(int i=low; i<=high; i++){
vector<TreeNode*> left=generateTrees(low, i-1);
vector<TreeNode*> right=generateTrees(i+1, high);
TreeNode *root;
for(int j=0; j<left.size(); j++){
for(int k=0; k<right.size(); k++){
root=new TreeNode(i);           //root必须放在着这个循环里!
root->left=left[j];
root->right=right[k];
res.push_back(root);
}
}
}
return res;
}
}

vector<TreeNode *> generateTrees(int n) {
vector<TreeNode*> res;
if(n==0){
res.push_back(NULL);
return res;
}
return generateTrees(1, n);
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: