国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

卡特蘭數,程序實現,遞歸,循環,BST和出入棧順序的應用

2019-11-08 18:24:13
字體:
來源:轉載
供稿:網友


卡特蘭數是組合數學中的一種數列,它的來歷和重要性可以自行百度,我主要說它的特征和編程實現。

 

前幾項是1, 1, 2, 5, 14, 42, 132……,

如果令h(0)=h(1)=1,那么h(n)=h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)*h(0) (n>=2)。

常用遞推公式h(n)=C(2n,n)/(n+1) =(2n)!/n!/(n+1)!,(n=0,1,2,...),還有很多變體。

 

利用程序來求解這些數值自然簡單。

比如

利用第一個遞推式的遞歸版本代碼

classSolution{

public:

   intnumTrees(intn){

       if(n== 0 || n == 1)return1;

       intret(0);

       for(inti(0); i < n; ++i)ret += numTrees(i)*numTrees(n- 1 - i);

       returnret;

   }//numTrees

};

利用第一個遞推式的迭代版本代碼,形式上是一致,省去重復計算,比遞歸的速度快。開辟了vector<int>G(n+ 1)這個數組,存儲中間計算結果,本質上是一種動態規劃,屬于“以土地換和平”的策略。

class Solution {

public:

   intnumTrees(int n) {

       vector<int>G(n + 1);

       G[0] =G[1] = 1;

       for(inti(2); i <= n; ++i) {

           intsum(0);

           for(intj(0); j < i; ++j) sum += G[j] * G[i - 1 - j];

           G[i]= sum;

       }//fori

       returnG[n];

   }//numTrees

};

利用最后那個公式直接求解。

class Solution {

public:

   intnumTrees(int n) {

       if(n == 0 || n == 1)return 1;

       longlongret(1);

       for(inti(n + 1); i <= n + n; ++i) ret *= i, ret /= i - n;

       ret /=n + 1;

       returnret;

   }//numTrees

};

以上都是直接求卡特蘭數列的某一項值。比較簡單。

進一步了解可知,該數列應用在很多實際問題中。比如棧的出入順序,BST的種類。

下面以搜索二叉樹的建立為例給出代碼,對于給定一個序列,建立BST,序列中元素的順序會影響樹的形狀。

比如{1,2},能建立起1為根,2為右孩子的BST。而{2,1}則建立起2為根,1為左孩子的BST。

該代碼對應leetcode 95題,核心部分為generateTrees_recur函數,遞歸出口是left>right,返回空子樹(即NULL)。

For(i)循環中,先得到leftRoots和rightRoots,分別是左半部分序列得到的子樹和右半部分序列得到的子樹,后面for(lch,rch)循環來交叉剛才得到的那些子樹。

對于每一個交叉,產生一個以i為根的新的子樹。

#include<stdio.h>

#include<vector>

using std::vector;

 

struct TreeNode {

   intval;

   TreeNode*left = NULL;

   TreeNode*right = NULL;

   TreeNode(intval_ = -1) :val(val_) {}

   ~TreeNode(){

       if(left) {delete left; left = NULL; }

       if(right) {delete right; right = NULL; }

   }//~Node

};

class Solution {

public:

   vector<TreeNode*>generateTrees(int n) {

       if(n == 0)return vector<TreeNode*>{};

       returngenerateTrees_recur(1, n);

   }//generateTrees

public:

   inttimes = 0;

   vector<TreeNode*>generateTrees_recur(int left,intright) {

       if(left > right)return vector<TreeNode*>{NULL};

       vector<TreeNode*>roots;

       for(inti(left); i <= right; ++i) {

           autoleftRoots = generateTrees_recur(left, i - 1);

           autorightRoots = generateTrees_recur(i + 1, right);

           intsizeOfLeft = (int)leftRoots.size();

           intsizeOfRight = (int)rightRoots.size();

           for(intlch(0); lch < sizeOfLeft; ++lch) {

               for(intrch(0); rch < sizeOfRight; ++rch) {

                   TreeNode*root = new TreeNode(i);

                   ++times;

                   root->left= leftRoots[lch];

                   root->right= rightRoots[rch];

                   roots.push_back(root);

               }//forrch

           }//forlch

       }//fori

       returnroots;

   }//generateTrees_recur

   voidPReOrder(TreeNode *root, vector<int>&order) {

       if(root == NULL) {

          order.push_back(-1);

           return;

       }//if

       order.push_back(root->val);

       preOrder(root->left,order);

       preOrder(root->right,order);

       return;

   }//preOrder

   voidprintVec(const vector<int>&vec) {

       for(autonum : vec)printf("%d ", num);putchar(10);

       return;

   }//printVec

   voiddestroyTree(TreeNode *root) {

       if(root) {

           deleteroot;

           root= NULL;

       }//if

       return;

   }//destroyTree

};

#define CRTDBG_MAP_ALLOC

#include<crtdbg.h>

int main() {

   _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF| _CRTDBG_LEAK_CHECK_DF);

   Solutionsol;

   intn(4);

   autotrees = sol.generateTrees(n);

   printf("times=%d/n", sol.times);

   for(autotree : trees) {

       vector<int>order;

       sol.preOrder(tree,order);

       sol.destroyTree(tree);

       sol.printVec(order);

   }//fortree

   return0;

}//main

generateTrees_recur返回的樹的個數正好對應一個卡塔蘭數。

參考上面的代碼,給出一個類似的。

讓遞歸函數generateTrees_recur返回vector<vector<int>>,

然后把對應的vector<int>,用createTree函數,先序建立tree。

得到vector<TreeNode*> trees。也完成了leetcode95題的功能。

我們再把思維在發散一下,vector<int>正好可以應用在別的問題里,比如出棧的順序。因此這份代碼也可以應用在求出棧順序的那個上面。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 隆化县| 凌云县| 九台市| 舒兰市| 五寨县| 满洲里市| 巴林右旗| 弥勒县| 平遥县| 盘山县| 扎鲁特旗| 海兴县| 卢湾区| 海安县| 锡林郭勒盟| 会宁县| 天气| 如东县| 托克托县| 黔南| 新蔡县| 渝中区| 清水县| 镇巴县| 霍州市| 马关县| 扶风县| 麻栗坡县| 甘谷县| 宜良县| 任丘市| 噶尔县| 旅游| 革吉县| 玉环县| 文安县| 长沙市| 仁化县| 长沙市| 宜昌市| 施秉县|