1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
private Map<Integer, List<TreeNode>> memo = new HashMap<>();

public List<TreeNode> allPossibleFBT(int n) {
if (memo.containsKey(n)) {
return memo.get(n);
}
List<TreeNode> ans = new ArrayList<>();
if (n == 1) {
ans.add(new TreeNode(0));
} else if (n % 2 == 1) {
for (int i = 1; i < n; i += 2) {
int j = n - 1 - i;
for (TreeNode left : allPossibleFBT(i)) {
for (TreeNode right : allPossibleFBT(j)) {
TreeNode currRoot = new TreeNode(0);
currRoot.left = left;
currRoot.right = right;
ans.add(currRoot);
}
}
}
}
memo.put(n, ans);
return ans;
}
}

需要意识到一个问题就是full binary tree中nodes的个数是奇数个. 这是关键.
如果给我们的值n是个偶数, 那是凑不成full binary tree的.
如果是奇数, 那我们就要想左树有几个, 右树有几个. 比如n == 7. 可以的组合是:
左: 1 右: 5
左: 3 右: 3
左: 5 右: 1
这样就转化为了subproblem了.

我们用memo来存之前求过的答案.

时间复杂度: O(n) 如果n是奇数, 我们有n / 2种情况, 每种情况只会求因此, 因为有memo.
空间复杂度: O(n) 一层一层下去, 左1, 右n, 然后是左1右n - 2, 然后是左1, 右n - 4…