日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

每天一道LeetCode-----生成由[1 : n]这n个数组成的所有二叉搜索树

發布時間:2024/4/19 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 每天一道LeetCode-----生成由[1 : n]这n个数组成的所有二叉搜索树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Unique Binary Search Trees

原題鏈接Unique Binary Search Trees

給定數值n,計算有多少種不同的二叉搜索樹能夠存儲1,2,...,n這n個數

二叉搜索樹滿足的條件

  • 當前根節點的值大于左子樹節點的值
  • 當前根節點的值小于右子樹節點的值
  • 左右子樹同樣是二叉搜索樹

根據上述規則可以看出,根節點值不同,形成的二叉搜索樹就不同,那么[1:n]范圍內的n個數就有n個不同的選擇

假設選取i作為根節點值,根據二叉搜索樹的規則,[1:i?1]這i-1個數在其左子樹上,[i+1:n]這n-i個數在其右子樹上

對于由[1:i?1]形成的左子樹,又可以采用上述方法進行分解

對于由[i+1:n]形成的右子樹,同樣可以采用上述方法進行分解

由于每個分解的范圍都是連續遞增的,所以無需考慮具體數值。另G(n)表示由連續的n個數形成的二叉搜索樹的個數

那么G(n)為所求解,假設以i作為分界點,那么左子樹為G(i-1),右子樹為G(n-i)

因為i可以取從1到n的任意一個數,所以G(n)=ni=1(G(i?1)?G(n?i))

需要對G(0)和G(1)特殊處理,令其為1,即G(0)=G(1)=1

代碼如下

class Solution { public:int numTrees(int n) {vector<int> dp(n + 1, 0);dp[0] = dp[1] = 1;for(int i = 2; i <= n; ++i){for(int j = 1; j <= i; ++j){//G(i) += G(j - 1) * G(n - j)dp[i] += dp[j - 1] * dp[i - j];}}return dp[n];} };

Unique Binary Search Trees II

原題鏈接Unique Binary Search Trees II

不再是計算有多少個不同的二叉搜索樹,而是將所有不同的二叉搜索樹構造出來:smile:

還是以上面的題為基礎,假設選擇i作為分界點,那么左子樹由[1:i?1]范圍的值組成,右子樹由[i+1:n]范圍內的值組成

通過[1:i?1]這i-1個數可以構成多個不同的二叉搜索樹,假設是leftTree1leftTree2,....,leftTreeL

通過[i+1:n]這n-i個數可以構成多個不同的二叉搜索樹,假設是rightTree1,rightTree2,...,rightTreeR

那么可知以i作為根節點的二叉搜索樹共有L?R個,另這些樹依次組成即可求出這L?R個樹

代碼如下

/*** 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) {return generateTrees(1, n); } private://返回由[start : end]組成的所有樹vector<TreeNode*> generateTrees(int start, int end){vector<TreeNode*> trees;//如果只有一個元素,直接構建返回if(start == end){trees.emplace_back(new TreeNode(start));return trees;}//范圍內無元素,直接返回if(start > end){return trees;}for(int i = start; i <= end; ++i){//以i作為分界點獲取左右兩部分的子樹集合vector<TreeNode*> leftTrees = generateTrees(start, i - 1);vector<TreeNode*> rightTrees = generateTrees(i + 1, end);//如果是空,手動增加nullptr節點,否則for循環進不去!!!if(leftTrees.empty()) leftTrees.emplace_back(nullptr);if(rightTrees.empty()) rightTrees.emplace_back(nullptr);//依次組合所有可能for(auto leftTree : leftTrees){for(auto rightTree : rightTrees){//構建以i為值的根節點,添加左右子樹,添加到結果中TreeNode *root = new TreeNode(i);root->left = leftTree;root->right = rightTree;trees.emplace_back(root);}}}//繼續返回上一層return trees;} };

這兩道題比較重要,真的很重要:cry:

對于如何構建二叉搜索樹,只需要將其拆分成左右兩部分,再組合集合。計算所有BST的數量利用的是動態規劃,公式推導一遍應該可以理解(Letex公式真的好用:smile:)

總結

以上是生活随笔為你收集整理的每天一道LeetCode-----生成由[1 : n]这n个数组成的所有二叉搜索树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。