Title

# 单链表转 BST 树 | 数组转 BST树

## 单链表转二叉树

{-1,0,1,2}

{1,0,2,-1}


typedef TreeNode Node;
/**
* struct TreeNode {
*	int val;
*	struct TreeNode *left;
*	struct TreeNode *right;
* };
*/
/**
* struct ListNode {
*	int val;
*	struct ListNode *next;
* };
*/

class Solution {
public:
/**
*
* @return TreeNode类
*/
// write code here
}
while(first!=tail && first->next!=tail) first = first->next->next,last = last->next;
Node *root = new Node(last->val);

root ->right = build(last->next,tail);
return root;
}
};



## 升序数组转二叉树

[-1,0,1,2]

{1,0,2,-1}



typedef TreeNode Node;
class Solution {
public:
/**
*
* @param num int整型vector
* @return TreeNode类
*/
TreeNode* sortedArrayToBST(vector<int>& num) {
if(num.size()<=0) return NULL;
return build(num,0 ,num.size()-1);
}

Node* build(vector<int>& a,int l,int r) {
if(l>r) return nullptr;
//         if(l==r) return new Node(a[l]);
int mid = l+r+1>>1;
Node * root = new Node(a[mid]);
root ->left = build(a,l,mid-1);
root ->right = build(a,mid+1,r);
return root;

}
};



## 中序遍历 和后续遍历序列 生成的二叉树

[2,1,3],[2,3,1]



typedef TreeNode Node;

class Solution {
public:
/**
*
* @param inorder int整型vector
* @param postorder int整型vector
* @return TreeNode类
*/
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
// write code here
int n = inorder.size(),m = postorder.size();
if(n!=m) return NULL;
return build(inorder,postorder,0,n-1,0,n-1);
}

Node* build(vector<int>&in,vector<int> &post,int il,int ir,int pl,int pr) {
if(il>ir || pl>pr) return  NULL;
//post order 左右 [根]  root-> pr
//inorder  左根右       root-> il+ir/2
int target = post[pr],in_root_idx=il;
for(int i=il;i<=ir;++i) {
if(in[i]==target) {
in_root_idx = i;
break;
}
}
Node* root = new Node(target);
int r_to_i = ir - in_root_idx;
root->left = build(in,post,il,in_root_idx-1,pl,pr-r_to_i-1);
root->right = build(in,post,in_root_idx+1,ir,pr-r_to_i,pr-1);
return root;

}

};



[1,2],[1,2]


typedef TreeNode Node;
typedef vector<int> Array;
class Solution {
public:
/**
*
* @param preorder int整型vector
* @param inorder int整型vector
* @return TreeNode类
*/
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
// write code here
int n = preorder.size(),m = inorder.size();
if(n!=m) return NULL;
return build(preorder,inorder,0,n-1,0,n-1);
}

Node* build(Array &pre,Array &in, int pl,int pr,int il,int ir) {
if(pl>pr || il>ir) return NULL;
int target = pre[pl];int root_idx=il;
for(int i=il;i<=ir;++i) {
if(in[i]==target){root_idx = i;break;}
}
Node* root = new Node(target);
int len = root_idx - il;
//先序，根左，右
root ->left = build(pre,in,pl+1,pl+len,il,root_idx-1);
root ->right = build(pre,in,pl+len+1,pr,root_idx+1,ir);

return root;
}
};



## 后序遍历生成BST



typedef TreeNode Node;
class Solution {
public:
/**
*
* @param n int整型
* @return TreeNode类vector
*/
vector<TreeNode*> generateTrees(int n) {
// write code here
return build(1,n);
}

vector<Node*> build(int l,int r) {
if(l>r) return {NULL};
vector<Node*> res;
for(int k=l;k<=r;++k) {
vector<Node*> left = build(l,k-1);
vector<Node*> right = build(k+1,r);
for(int i=0;i<left.size();++i) {
for(int j=0;j<right.size();++j) {
Node* root = new Node(k);
root->left = left[i];
root->right = right[j];
res.push_back(root);
}
}
}
return res;

}

};



## 输入N 求二叉树生成的个数

分析：
f(1) = 1；
f(2) = f(1)+f(1)；
f(3) = f(2)+f(1)f(1)+f(2)；
f(4) = f(3)+f(1)f(2)+f(2)f(1)+f(3)
f(5) = f(4)+f(1)f(3)+f(2)f(2)f(3)*f(1)+f(4)

考虑根节点，设对于任意根节点k，有f(k)种树的可能。
比k小的k-1个元素构成k的左子树。则左子树有f(k-1)种情况。
比k大的n-k个元素构成k的右子树。则右子树有f(n-k)种情况。
易知，左右子树相互独立，所以f(k)=f(k-1)*f(n-k)。
综上，对于n，结果为k取1,2,3,...,n时，所有f(k)的和。

根据上述思路可以用简单的递归方法快速解决。
现在考虑非递归解法，用数组记录每个f(i)的值，记f(0)=1,f(1)=1。
根据公式：f(k)=f(k-1)*f(n-k)，访问数组中的元素。
循环求和，结果更新到数组中。
(PS:此题可用Catalan number快速求解：对于n，答案为1/(n+1)*nC2n。)




class Solution {
public:
/**
*
* @param n int整型
* @return int整型
*/
int numTrees(int n) {
// write code here
if(n<0) return -1;
if(n==0) return 1;
int dp[n+1];
memset(dp,0,sizeof dp);
dp[0] = 1;
dp[1] = 1;

for(int i=2;i<=n;++i) {
for(int j=0;j<i;++j) {
dp[i] += dp[j]*dp[i-j-1];
}
}
return dp[n];

}

};


posted @ 2021-01-25 17:16  .geek  阅读(116)  评论(0编辑  收藏  举报