This question is very similar to other generation problems. For example, generate the perfect parentheses. The only different thing is this time we need to generate a node and tree.
The hardest thing about using backtracing to generate different trees is the memory address problem. As the tree is using pointers to connect the node, even if we backtrace, the node we just generated would not disappear, and also we need to add the root to the result, and in normal dfs, we can only add the leaf node to the result.
How to solve it?
1. About the memory address problem:
we need to make a deep copy function which is the same with clone a tree problem.
TreeNode* clone(TreeNode* root){
if(root == nullptr)return nullptr;
TreeNode* cloneRoot = new TreeNode(0);
cloneRoot->left = clone(root->left);
cloneRoot->right = clone(root->right);
return cloneRoot;
}
2. About how to add the root to the result:
we can try to build our full binary tree from the bottom to the top. A full binary tree's subtree would have exactly the same structure and pattern. Our dfs just need to specify how many nodes we gonna make and let it recursively generate it. Also, we know a full binary tree's left subtree and right subtree's nodes sum up, and adding one would be n. So, if we want to generate a different kind of full binary tree, we need to give the left tree and right tree different weights.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
TreeNode* clone(TreeNode* root){
if(root == nullptr)return nullptr;
TreeNode* cloneRoot = new TreeNode(0);
cloneRoot->left = clone(root->left);
cloneRoot->right = clone(root->right);
return cloneRoot;
}
public:
vector<TreeNode*> allPossibleFBT(int n) {
vector<TreeNode*> res;
if(n == 1)res.push_back(new TreeNode(0));
if(n % 2 == 0)return res;
for(int i = 1; i < n; i+=2){
//give different weight to left and right by giving the number of nodes
vector<TreeNode*> leftSubtree = allPossibleFBT(i);
vector<TreeNode*> rightSubtree = allPossibleFBT(n - 1 - i);
//generate the nodes and connect the nodes.
for(auto lft : leftSubtree){
for(auto rght : rightSubtree){
TreeNode* root = new TreeNode(0);
root->left = clone(lft);
root->right = clone(rght);
//add the root to the answer set and let the programe to generate different pattern
res.push_back(root);
}
}
}
return res;
}
};