Topic:
Given n, generate all structurally unique BST 's (binary search trees) that store values 1 ... n.
For example,
Given N = 3, your program should return all 5 unique BST ' s shown below.
1 3 3 2 1 \// /\ 3 2 1 1 3 2 / / \ 2 1 2 3
Confused what "{1,#,2,3}"
means? > read more on how binary tree is serialized on OJ.
idea: The problem is to solve all feasible two-fork search trees, from the unique binary search trees we already know how to get all the viable two-fork lookup trees. Each time we traverse from 1~n to select a point I as the root of the tree, the combination of the left subtree and the numtrees of the right subtree numtrees the sum of the combinations of the current root. According to the definition of binary search tree, the number of nodes of left subtree is (i-1) and the right subtree is (n-i). The idea is to construct an auxiliary function, we select one node at a time as the root, and then recursively solve all the results of the left and right subtree of this root. Finally, according to the return subtree of the left and right subtree, select the root node in turn. After it is constructed, it is returned as the result of the current tree.
This problem thinking on a difficult point, is how to connect all the left and right sub-tree and root node, we here will be recursive into the loop inside , using this technique, can be extracted from the root node and the left and right sub-tree nodes , while the recursion is still produced by the root node of the subtree. Another point, how to design a recursive end condition, when Start > End, the description out of range, the end of recursion, there is no node, push (NULL)
Attention:
1. Set recursive termination conditions and special cases.
if (Start > End) { trees.push_back (NULL); return trees; } if (start = = end) { trees.push_back (new TreeNode (start)); return trees; }
2. Trick: Recursion is placed in the loop, pulling away from the root node and the left and right sub-tree nodes
It is possible to generate all the left and right subtree with I as the root node. I takes a value of start to end vector<treenode*> lefttree = Generatetrees_helper (start, i-1); vector<treenode*> Righttree = Generatetrees_helper (i+1, end);
3. How to connect the root node and the left and right sub-tree, the left and the sub-tree recursive return is still the root node of the tree, respectively, to the current node of the left children and children, and then add the current node to the tree.
treenode* root = new TreeNode (i); Root->left = Lefttree[j]; Root->right = Righttree[k]; Trees.push_back (root); Trees saving the current root node
4. Note that when connected, the viable number = left subtree * Right subtree, note the loop condition, Zuozi all subtrees of all subtrees * right subtree.
5. Our auxiliary function, which is always maintained is the root node.
Complexity: NP problem
AC Code:
/** * Definition for binary tree * struct TreeNode {* int val; * TreeNode *left; * TreeNode *right; * Tre Enode (int x): Val (x), left (null), right (NULL) {} *}; */class Solution {Public:vector<treenode *> generatetrees (int n) {return generatetrees_helper (1, N); }private:vector<treenode*> generatetrees_helper (int start, int end) {vector<treenode*> trees; if (Start > End) {trees.push_back (NULL); return trees; } if (start = = end) {trees.push_back (new TreeNode (start)); return trees; } for (int i = start; I <= end; i++) {//produces all possible of the left and right subtree with I as the root node. I takes a value of start to end vector<treenode*> Lefttree = Generatetrees_helper (start, i-1); vector<treenode*> Righttree = Generatetrees_helper (i+1, end); All possible connections to all possible and right subtrees of the left subtree. Lefttree[0] Represents the first node. for (int j =0; J < Lefttree.size (); J + +) {for (int k = 0; k < righttree.size (); k++) {TreeNode * Root = new TreeNode (i); Root->left = Lefttree[j]; Root->right = Righttree[k]; Trees.push_back (root); Trees save the current root node}}} return trees; }};
[C + +] leetcode:92 Unique Binary Search Trees II