递归的练习,快速排序的反向过程。
题目在下面,大意是求1-n的数字构成的二叉排序树的所有数据情形。这个题目还是值得注意的,最直观的方法是求得全排列,再构造排序树,但是这样的方案不是最优的,比如1-2-3和3-2-1的排序树结构是一样的,
考虑一下快速排序的实现,快速排序是对一个排列,进行排序,这里的处理有些类似。
取一个数字出来,作为中间父节点,左边的数据作为左子树,右边的数据作为右子树,左右再一次递归,实现出完整的树,看起来还比较清晰,需要注意的是,由于左子树和右子树是独立展开的,需要用集合来进行保存,再使用笛卡尔积方式组合起来和中间数据一起构成数据集合。
95. Unique Binary Search Trees II
力扣
Given an integer n, return all the structurally unique BST's (binary search trees), which has exactly n nodes of unique values from 1 to n. Return the answer in any order.
Example 1:
Input: n = 3
Output: [[1,null,2,null,3],[1,null,3,2],[2,1,3],[3,1,null,null,2],[3,2,null,1]]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-binary-search-trees-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
下面的实现是采用数组保存集合,在这个题目里可以直接用树结构来保存结果。
/**
* 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<TreeNode*> ans;
TreeNode* thead;
int v[20];
void add(TreeNode* head, TreeNode* k) {
if (k->val < head->val) {
if (head->left == nullptr) {
head->left = k;
} else {
add(head->left, k);
}
} else {
if (head->right == nullptr) {
head->right = k;
} else {
add(head->right, k);
}
}
}
TreeNode* getTree(vector<int>& v, int n) {
TreeNode* head = new TreeNode(v[0]);
for (int i = 1; i < n; i++) {
TreeNode* node = new TreeNode(v[i]);
add(head, node);
}
return head;
}
void addv(vector<vector<int>>& a, vector<vector<int>>& b) {
for (int i = 0; i < b.size(); i++) {
a.push_back(b[i]);
}
}
vector<int> merge2(vector<int>& a, vector<int>& b) {
vector<int> t = a;
for (int i = 0; i < b.size(); i++) {
t.push_back(b[i]);
}
return t;
}
vector<vector<int>> mergev(vector<vector<int>>& a,
vector<vector<int>>& b) {
if (b.size() == 0) return a;
vector<vector<int>> ret;
for (int i = 0; i < a.size(); i++) {
for (int j = 0; j < b.size(); j++) {
ret.push_back(merge2(a[i], b[j]));
}
}
return ret;
}
//b-begin, e-end, p-the position
vector<vector<int>> get2(int b, int e, int p) {
vector<vector<int>> ret;
// if (p == num) {
// return ret;
// }
for (int i = b; i <= e; i++) {
v[p] = i;
// if (p == num-1) {
if (b == e) {
ret.push_back({v[p]});
continue;
}
// p++;
//left, the position is after p, so it is p+1
vector<vector<int>> left = get2(b, i-1, p+1);
//right, the position is after the end of left
vector<vector<int>> rig = get2(i+1, e, p+1+i-b);//i //1 2 3 7 5 5 4
// p--;
vector<vector<int>> tt(1, {v[p]});
vector<vector<int>> t1 = mergev(tt, left);
vector<vector<int>> t = mergev(t1, rig);
addv(ret, t);
}
return ret;
}
vector<TreeNode*> generateTrees(int n) {
vector<vector<int>> ret = get2(1, n, 0);
for (int i = 0; i < ret.size(); i++) {
thead = getTree(ret[i], n);
ans.push_back(thead);
}
return ans;
}
};