Leetcode 95. 不同的二叉搜尋樹 II C++
阿新 • • 發佈:2018-11-11
題目描述
思路
首先,本題是另外一個題的升級版,詳細解答。這兩個題都是用到了動態規劃的思想,大的思路是差不多的。不過,這個題要複雜得多。解本題之前一定要先去看一看上一個題的思路。
本題思路,和上一個題一樣,通過迴圈歷遍每一個元素。以這個元素作為根節點,那麼比它小的元素就只能是屬於它的左子樹,比它大的節點屬於它的右子樹。
那麼剩下的問題,就是求左子樹的所有可能的集合,和右子樹的所有可能的集合。這兩個問題和原問題本質上是一樣求法。這樣問題就被劃分為了兩個子問題。最後再將兩邊所有可能的組合都合起來,構成一棵樹。
每當確定了一個根節點(最外層迴圈),之後的問題就是一個動態規劃的問題。將所有可能的左子樹的組合存在lefts中,右子樹的可能組合放在rights中。最後再組合。
注意:在理解上,對這種遞迴問題,不要試圖通過在腦海裡一步一步推演驗證,那樣實在有些難。最好用遞迴的思想去理解
解答
C++
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<TreeNode*> generateTrees(int n) {
vector< TreeNode*> res;
if(n<1) return res;
return genBST(1,n);
}
vector<TreeNode*> genBST(int start, int end) //該函式,返回的是從start開始,以enb結尾的元素生成搜尋二叉樹的集合
{
vector<TreeNode*> res;
if(start>end) res.push_back(NULL);
for(int i=start; i<= end; ++i) //根節點為 i時,生成二叉搜尋樹
{
vector<TreeNode*> lefts=genBST(start,i-1); //這裡返回的是一個集合,表示以i 為根時,左子樹可能的所有集合
vector<TreeNode*> rights=genBST(i+1,end); //右子樹
for(auto left:lefts)
{
for(auto right:rights)
{
TreeNode* root=new TreeNode(i);
root->left=left;
root->right=right;
res.push_back(root);
}
}
}
return res;
}
};
Python
正好在網上看到一個Python解答,跟著練一練Python。自己還太弱。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def generateTrees(self, n):
"""
:type n: int
:rtype: List[TreeNode]
"""
if n<1:
return []
else:
return self.genBST(1,n)
def genBST(self,start,end):
res=[]
if(start>end):
return [None]
else:
for i in range(start,end+1):
lefts=self.genBST(start,i-1)
rights=self.genBST(i+1,end)
for left in lefts:
for right in rights:
root = TreeNode(i)
root.left = left
root.right = right
res.append(root)
return res