递归练习0208-Leetcode-95不同的二叉搜索树

递归的练习,快速排序的反向过程。

题目在下面,大意是求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;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值