C++實現(xiàn)LeetCode(95.獨一無二的二叉搜索樹之二)
[LeetCode] 95. Unique Binary Search Trees II 獨一無二的二叉搜索樹之二
Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1 ... n.
Example:
Input: 3
Output:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
Explanation:
The above output corresponds to the 5 unique BST's shown below:1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
這道題是之前的 Unique Binary Search Trees 的延伸,之前那個只要求算出所有不同的二叉搜索樹的個數(shù),這道題讓把那些二叉樹都建立出來。這種建樹問題一般來說都是用遞歸來解,這道題也不例外,劃分左右子樹,遞歸構(gòu)造。這個其實是用到了大名鼎鼎的分治法 Divide and Conquer,類似的題目還有之前的那道 Different Ways to Add Parentheses 用的方法一樣,用遞歸來解,劃分左右兩個子數(shù)組,遞歸構(gòu)造。剛開始時,將區(qū)間 [1, n] 當作一個整體,然后需要將其中的每個數(shù)字都當作根結(jié)點,其劃分開了左右兩個子區(qū)間,然后分別調(diào)用遞歸函數(shù),會得到兩個結(jié)點數(shù)組,接下來要做的就是從這兩個數(shù)組中每次各取一個結(jié)點,當作當前根結(jié)點的左右子結(jié)點,然后將根結(jié)點加入結(jié)果 res 數(shù)組中即可,參見代碼如下:
解法一:
class Solution {
public:
vector<TreeNode*> generateTrees(int n) {
if (n == 0) return {};
return helper(1, n);
}
vector<TreeNode*> helper(int start, int end) {
if (start > end) return {nullptr};
vector<TreeNode*> res;
for (int i = start; i <= end; ++i) {
auto left = helper(start, i - 1), right = helper(i + 1, end);
for (auto a : left) {
for (auto b : right) {
TreeNode *node = new TreeNode(i);
node->left = a;
node->right = b;
res.push_back(node);
}
}
}
return res;
}
};
我們可以使用記憶數(shù)組來優(yōu)化,保存計算過的中間結(jié)果,從而避免重復(fù)計算。注意這道題的標簽有一個是動態(tài)規(guī)劃 Dynamic Programming,其實帶記憶數(shù)組的遞歸形式就是 DP 的一種,memo[i][j] 表示在區(qū)間 [i, j] 范圍內(nèi)可以生成的所有 BST 的根結(jié)點,所以 memo 必須是一個三維數(shù)組,這樣在遞歸函數(shù)中,就可以去 memo 中查找當前的區(qū)間是否已經(jīng)計算過了,是的話,直接返回 memo 中的數(shù)組,否則就按之前的方法去計算,最后計算好了之后要更新 memo 數(shù)組,參見代碼如下:
解法二:
class Solution {
public:
vector<TreeNode*> generateTrees(int n) {
if (n == 0) return {};
vector<vector<vector<TreeNode*>>> memo(n, vector<vector<TreeNode*>>(n));
return helper(1, n, memo);
}
vector<TreeNode*> helper(int start, int end, vector<vector<vector<TreeNode*>>>& memo) {
if (start > end) return {nullptr};
if (!memo[start - 1][end - 1].empty()) return memo[start - 1][end - 1];
vector<TreeNode*> res;
for (int i = start; i <= end; ++i) {
auto left = helper(start, i - 1, memo), right = helper(i + 1, end, memo);
for (auto a : left) {
for (auto b : right) {
TreeNode *node = new TreeNode(i);
node->left = a;
node->right = b;
res.push_back(node);
}
}
}
return memo[start - 1][end - 1] = res;
}
};
到此這篇關(guān)于C++實現(xiàn)LeetCode(95.獨一無二的二叉搜索樹之二)的文章就介紹到這了,更多相關(guān)C++實現(xiàn)獨一無二的二叉搜索樹之二內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++數(shù)據(jù)結(jié)構(gòu)二叉搜索樹的實現(xiàn)應(yīng)用與分析
- C++實現(xiàn)LeetCode(173.二叉搜索樹迭代器)
- C++實現(xiàn)LeetCode(109.將有序鏈表轉(zhuǎn)為二叉搜索樹)
- C++實現(xiàn)LeetCode(108.將有序數(shù)組轉(zhuǎn)為二叉搜索樹)
- C++實現(xiàn)LeetCode(99.復(fù)原二叉搜索樹)
- C++實現(xiàn)LeetCode(98.驗證二叉搜索樹)
- C++實現(xiàn)LeetCode(96.獨一無二的二叉搜索樹)
- C++ 二叉搜索樹(BST)的實現(xiàn)方法
- C++ 超詳細快速掌握二叉搜索樹
相關(guān)文章
C語言可變參數(shù)與函數(shù)參數(shù)的內(nèi)存對齊詳解
這篇文章主要為大家詳細介紹了C語言可變參數(shù)與函數(shù)參數(shù)的內(nèi)存對齊,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03
Visual C++程序設(shè)計中Windows GDI貼圖閃爍的解決方法
這篇文章主要介紹了Visual C++程序設(shè)計中Windows GDI貼圖閃爍的解決方法,分析了GDI貼圖閃爍的常見原因及其具體解決方法,具有一定參考借鑒價值,需要的朋友可以參考下2015-01-01

