Leetcode日记4-LeetCode 95 Unique Binary Search Trees

本文详细解析了如何使用递归算法生成所有中序遍历为1到n的二叉树。通过定义makeTree函数,实现以指定根节点值构建树的过程,并考虑左右子树的生成。最后通过实例展示了算法实现步骤,提供了深入理解二叉树生成算法的视角。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(2015/11/15)

LeetCode-95 Unique Binary Search Trees II:(Medium)(do more time)

题目大意:给定n,生成所有中序遍历为1...n的二叉树。


解题思路:

1)定义函数:void makeTree(int rootval, vector<int> allnodes, vector<TreeNode *> &ans)

rootval:为根结点的值。

allnodes:为此树中所有结点的值的集合。

ans:存放以rootval为根结点的值的所有可能的二叉树。


makeTree函数的执行过程:

1)以rootval作为根结点的值,比rootval大的值放在右子树值的集合,比rootval小的值放在左子树值的集合。

2)递归调用makeTree,生成左右子树的集合。

3)根据返回的左右子树集合的大小,生成以rootval为根结点值的树。

class Solution {
public:
    vector<TreeNode*> generateTrees(int n){
        vector<int> allnodes;
        for(int i = 1; i <= n; i++) allnodes.push_back(i);
        
        vector<TreeNode *> ans;
        
        if(n == 0){
            TreeNode *tmp = NULL;
            ans.push_back(tmp);
        }
        
        for(vector<int>::size_type i = 0; i < allnodes.size(); i++)
            makeTree(allnodes[i], allnodes, ans);
            
        return ans;
    }
    
    void makeTree(int rootval, vector<int> allnodes, vector<TreeNode *> &ans){
        vector<int> leftnodes, rightnodes;
		for (vector<int>::size_type i = 0; i < allnodes.size(); i++){
			if (allnodes[i] > rootval) rightnodes.push_back(allnodes[i]);
			else if (allnodes[i] < rootval) leftnodes.push_back(allnodes[i]);
		}
		
		vector<TreeNode *> leftsubtree, rightsubtree;
		for(vector<int>::size_type i = 0; i < leftnodes.size(); i++)
		    makeTree(leftnodes[i], leftnodes, leftsubtree);
		for(vector<int>::size_type i = 0; i < rightnodes.size(); i++)
		    makeTree(rightnodes[i], rightnodes, rightsubtree);
		    
		TreeNode *tmp;
		if(leftsubtree.size() == 0 && rightsubtree.size() == 0){
		    tmp = new TreeNode(rootval);
		    ans.push_back(tmp);
		    return;
		}
		
        if(leftsubtree.size() != 0 && rightsubtree.size() == 0){
            for(vector<TreeNode *>::size_type i = 0; i < leftsubtree.size(); i++){
                tmp = new TreeNode(rootval);
                tmp->right = NULL;
                tmp->left = leftsubtree[i];
                ans.push_back(tmp);
            }
        }
        
        if(rightsubtree.size() != 0 && leftsubtree.size() == 0){
            for(vector<TreeNode *>::size_type i = 0; i < rightsubtree.size(); i++){
                tmp = new TreeNode(rootval);
                tmp->right = rightsubtree[i];
                tmp->left = NULL;
                ans.push_back(tmp);
            }
        }
        if(rightsubtree.size() != 0 && leftsubtree.size() != 0)
        {
            for(vector<TreeNode *>::size_type i = 0; i < leftsubtree.size(); i++){
                for(vector<TreeNode *>::size_type j = 0; j < rightsubtree.size(); j++){
                    tmp = new TreeNode(rootval);
                    tmp->right = rightsubtree[j];
                    tmp->left = leftsubtree[i];
                    ans.push_back(tmp);
                }
            }
        }
		return;
    }
};

解题体验:

首先看到这种题不要觉得难就不去思考,要把能想到的所有可能解法,解题思路写下来。

思路有了之后就要编程实现。这并不容易。

正确的算法及实现,其结构(框架)一定是清晰的。要在纸上多验证,算法的框架清晰了之后编程实现就容易了。

(比如此题:一定要想清楚什么时候new一个结点,这个结点怎么和父结点连接(如何把解传递给调用函数),怎么才能不漏掉解)



转载于:https://my.oschina.net/u/2463708/blog/530612

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值