22考研DS(2021-05-31)
1.力扣95. 不同的二叉搜索树 II
给你一个整数 n ,请你生成并返回所有由 n 个节点组成且节点值从 1 到 n 互不相同的不同 二叉搜索树 。可以按 任意顺序 返回答案。
示例 1:
输入:n = 3
输出:[[1,null,2,null,3],[1,null,3,2],[2,1,3],[3,1,null,null,2],[3,2,null,1]]
示例 2:
输入:n = 1
输出:[[1]]
提示:
1 <= n <= 8
题解:
二叉树的话则中序遍历顺序一定有序
假设根节点root是数字K,则root是在L-R之间的一个数[L----k-1 – k – k+1----R],
左子树[L,k-1],右子树[k+1,R]
从左子树和右子树中分别选择一个节点作为root的左右子树
1-n形成的二叉搜索树为卡特兰数
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
//二叉树的话则中序遍历顺序一定有序
//假设根节点root是数字K,则root是在L-R之间的一个数[L----k-1 -- k -- k+1----R],
//左子树[L,k-1],右子树[k+1,R]
//从左子树和右子树中分别选择一个节点作为root的左右子树
//1-n形成的二叉搜索树为卡特兰数
vector<TreeNode*> generateTrees(int n) {
if(!n) return {};
return dfs(1,n);
}
vector<TreeNode*> dfs(int l,int r){
if(l>r) return {nullptr}; //树为空
vector<TreeNode*> res;
for(int i=l;i<=r;i++){ //遍历树的root
auto lc=dfs(l,i-1),rc=dfs(i+1,r);
for(auto l:lc){
for(auto r:rc){
//i为根节点
auto root=new TreeNode(i);
root->left=l;
root->right=r;
res.push_back(root);
}
}
}
return res;
}
};
2.力扣96. 不同的二叉搜索树
给你一个整数 n
,求恰由 n
个节点组成且节点值从 1
到 n
互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
示例 1:
输入:n = 3
输出:5
示例 2:
输入:n = 1
输出:1
提示:
1 <= n <= 19
题解:
方法一:直接用卡特兰公式
方法二:暴力搜索
假设根节点root是数字K,则root是在L-R之间的一个数[L----k-1 – k – k+1----R],
左子树[L,k-1],右子树[k+1,R]
从左子树left和右子树right中分别选择一个节点作为root的左右子树
方案数:f(left)*f(right)
left=k-1-l+1
right=k-(k+1)+1
f(i)=求和f(j-1)*f(r-j-1);
代码:
class Solution {
public:
/*
方法一:直接用卡特兰公式
方法二:暴力搜索
假设根节点root是数字K,则root是在L-R之间的一个数[L----k-1 -- k -- k+1----R],
左子树[L,k-1],右子树[k+1,R]
从左子树left和右子树right中分别选择一个节点作为root的左右子树
方案数:f(left)*f(right)
left=k-1-l+1
right=k-(k+1)+1
f(i)=求和f(j-1)*f(r-j-1);
*/
int numTrees(int n) {
vector<int> f(n+1);
f[0]=1; //左子树为空
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
f[i]+=f[j-1]*f[i-j];
}
}
return f[n];
}
};
3.力扣107. 二叉树的层序遍历 II
给定一个二叉树,返回其节点值自底向上的层序遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
例如:
给定二叉树 [3,9,20,null,null,15,7],
3
/
9 20
/
15 7
返回其自底向上的层序遍历为:
[
[15,7],
[9,20],
[3]
]
题解:
自顶向下,从左到右的结果reverse
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> res;
queue<TreeNode*> q;
if(root) q.push(root);
while(q.size()){
vector<int> level;
int len=q.size();
while(len--){
auto t=q.front();
q.pop();
level.push_back(t->val);
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
res.push_back(level);
}
reverse(res.begin(),res.end());
return res;
}
};
4.力扣102. 二叉树的层序遍历
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7],
3
/
9 20
/
15 7
返回其层序遍历结果:
[
[3],
[9,20],
[15,7]
]
题解:
利用队列层序遍历
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
queue<TreeNode*> q;
if(root) q.push(root);
while(q.size()){
vector<int> level;
int len=q.size();
while(len--){
auto t=q.front();
q.pop();
level.push_back(t->val);
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
res.push_back(level);
}
return res;
}
};