894. 所有可能的真二叉树(中等)

没做出来,难受 😫
核心思想
记忆化搜索 记录n个节点时,能够形成的真二叉树。
看注释吧~
ps: 节点是复用的,也就是会有不同节点指向同一个节点。
代码
class Solution {
// map存储 剩余n个节点时 能够形成的真二叉树 防止重复计算
HashMap<Integer, List<TreeNode>> v;
public List<TreeNode> allPossibleFBT(int n) {
v = new HashMap<>();
return allPossibleFBTHelper(n);
}
private List<TreeNode> allPossibleFBTHelper(int n){
// curList 存储 以当前节点为根节点的所有真二叉树
List<TreeNode> curList = new ArrayList<>();
if(n == 1){
curList.add(new TreeNode(0));
return curList;
}
// 留一个给根节点 i个节点给左子树 必须是奇数才能建成真二叉树 所以i+=2
for(int i = 1; i < n; i+=2){
List<TreeNode> leftTree = new ArrayList<>();
List<TreeNode> rightTree = new ArrayList<>();
if(v.containsKey(i)){
leftTree = v.get(i);
}
else{
leftTree = allPossibleFBTHelper(i);
}
if(v.containsKey(n - i - 1)){
rightTree = v.get(n - i - 1);
}
else{
rightTree = allPossibleFBTHelper(n - i - 1);
}
// 获取所有左右子树的种类 接在当前根节点上
for(int left = 0; left < leftTree.size(); left++){
for(int right = 0; right < rightTree.size(); right++){
TreeNode root = new TreeNode(0);
root.left = leftTree.get(left);
root.right = rightTree.get(right);
curList.add(root);
}
}
}
v.put(n, curList);
return curList;
}
}

浙公网安备 33010602011771号