Leetcode日記4-LeetCode 95 Unique Binary Search Trees

(2015/11/15)node

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:爲根結點的值。spa

allnodes:爲此樹中全部結點的值的集合。code

ans:存放以rootval爲根結點的值的全部可能的二叉樹。遞歸


makeTree函數的執行過程:ci

1)以rootval做爲根結點的值,比rootval大的值放在右子樹值的集合,比rootval小的值放在左子樹值的集合。io

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一個結點,這個結點怎麼和父結點鏈接(如何把解傳遞給調用函數),怎麼才能不漏掉解)

相關文章
相關標籤/搜索