树
递归
记忆化搜索
动态规划
二叉树
题目描述
给你一个整数 n
,请你找出所有可能含 n
个节点的 真二叉树 ,并以列表形式返回。答案中每棵树的每个节点都必须符合 Node.val == 0
。
答案的每个元素都是一棵真二叉树的根节点。你可以按 任意顺序 返回最终的真二叉树列表。
真二叉树 是一类二叉树,树中每个节点恰好有 0
或 2
个子节点。
示例 1:
输入: n = 7
输出: [[0,0,0,null,null,0,0,null,null,0,0],[0,0,0,null,null,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,null,null,null,null,0,0],[0,0,0,0,0,null,null,0,0]]
示例 2:
输入: n = 3
输出: [[0,0,0]]
提示:
解法
方法一:记忆化搜索
如果 $n=1$,直接返回单个节点的列表。
如果 $n \gt 1$,我们可以枚举左子树的节点数量 $i$,那么右子树的节点数量为 $n-1-i$。对于每种情况,我们递归地构造左子树和右子树的所有可能的真二叉树。然后将左子树和右子树两两组合,得到所有可能的真二叉树。
此过程可以用记忆化搜索,避免重复计算。
时间复杂度 $O(\frac{2^n}{\sqrt{n}})$,空间复杂度 $O(\frac{2^n}{\sqrt{n}})$。其中 $n$ 是节点数量。
Python3 Java C++ Go TypeScript Rust C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 # Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution :
def allPossibleFBT ( self , n : int ) -> List [ Optional [ TreeNode ]]:
@cache
def dfs ( n : int ) -> List [ Optional [ TreeNode ]]:
if n == 1 :
return [ TreeNode ()]
ans = []
for i in range ( n - 1 ):
j = n - 1 - i
for left in dfs ( i ):
for right in dfs ( j ):
ans . append ( TreeNode ( 0 , left , right ))
return ans
return dfs ( n )
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 /**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private List < TreeNode >[] f ;
public List < TreeNode > allPossibleFBT ( int n ) {
f = new List [ n + 1 ] ;
return dfs ( n );
}
private List < TreeNode > dfs ( int n ) {
if ( f [ n ] != null ) {
return f [ n ] ;
}
if ( n == 1 ) {
return List . of ( new TreeNode ());
}
List < TreeNode > ans = new ArrayList <> ();
for ( int i = 0 ; i < n - 1 ; ++ i ) {
int j = n - 1 - i ;
for ( var left : dfs ( i )) {
for ( var right : dfs ( j )) {
ans . add ( new TreeNode ( 0 , left , right ));
}
}
}
return f [ n ] = ans ;
}
}
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
28
29
30
31
32
33
34
35
36 /**
* 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 {
public :
vector < TreeNode *> allPossibleFBT ( int n ) {
vector < vector < TreeNode *>> f ( n + 1 );
function < vector < TreeNode *> ( int ) > dfs = [ & ]( int n ) -> vector < TreeNode *> {
if ( f [ n ]. size ()) {
return f [ n ];
}
if ( n == 1 ) {
return vector < TreeNode *> { new TreeNode ()};
}
vector < TreeNode *> ans ;
for ( int i = 0 ; i < n - 1 ; ++ i ) {
int j = n - 1 - i ;
for ( auto left : dfs ( i )) {
for ( auto right : dfs ( j )) {
ans . push_back ( new TreeNode ( 0 , left , right ));
}
}
}
return f [ n ] = ans ;
};
return dfs ( n );
}
};
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
28
29
30
31
32 /**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func allPossibleFBT ( n int ) [] * TreeNode {
f := make ([][] * TreeNode , n + 1 )
var dfs func ( int ) [] * TreeNode
dfs = func ( n int ) [] * TreeNode {
if len ( f [ n ]) > 0 {
return f [ n ]
}
if n == 1 {
return [] * TreeNode { & TreeNode { Val : 0 }}
}
ans := [] * TreeNode {}
for i := 0 ; i < n - 1 ; i ++ {
j := n - 1 - i
for _ , left := range dfs ( i ) {
for _ , right := range dfs ( j ) {
ans = append ( ans , & TreeNode { 0 , left , right })
}
}
}
f [ n ] = ans
return ans
}
return dfs ( n )
}
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
28
29
30
31
32
33
34
35
36
37 /**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/
function allPossibleFBT ( n : number ) : Array < TreeNode | null > {
const f : Array < Array < TreeNode | null >> = new Array ( n + 1 ). fill ( 0 ). map (() => []);
const dfs = ( n : number ) : Array < TreeNode | null > => {
if ( f [ n ]. length ) {
return f [ n ];
}
if ( n === 1 ) {
f [ n ]. push ( new TreeNode ( 0 ));
return f [ n ];
}
const ans : Array < TreeNode | null > = [];
for ( let i = 0 ; i < n - 1 ; ++ i ) {
const j = n - 1 - i ;
for ( const left of dfs ( i )) {
for ( const right of dfs ( j )) {
ans . push ( new TreeNode ( 0 , left , right ));
}
}
}
return ( f [ n ] = ans );
};
return dfs ( n );
}
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 // Definition for a binary tree node.
// #[derive(Debug, PartialEq, Eq)]
// pub struct TreeNode {
// pub val: i32,
// pub left: Option<Rc<RefCell<TreeNode>>>,
// pub right: Option<Rc<RefCell<TreeNode>>>,
// }
//
// impl TreeNode {
// #[inline]
// pub fn new(val: i32) -> Self {
// TreeNode {
// val,
// left: None,
// right: None
// }
// }
// }
use std :: cell :: RefCell ;
use std :: rc :: Rc ;
impl Solution {
pub fn all_possible_fbt ( n : i32 ) -> Vec < Option < Rc < RefCell < TreeNode >>>> {
let mut f : Vec < Option < Vec < Option < Rc < RefCell < TreeNode >>>>>> = vec! [ None ; ( n + 1 ) as usize ];
Self :: dfs ( n , & mut f )
}
fn dfs (
n : i32 ,
f : & mut Vec < Option < Vec < Option < Rc < RefCell < TreeNode >>>>>> ,
) -> Vec < Option < Rc < RefCell < TreeNode >>>> {
if let Some ( ref result ) = f [ n as usize ] {
return result . clone ();
}
let mut ans = Vec :: new ();
if n == 1 {
ans . push ( Some ( Rc :: new ( RefCell :: new ( TreeNode :: new ( 0 )))));
return ans ;
}
for i in 0 .. n - 1 {
let j = n - 1 - i ;
for left in Self :: dfs ( i , f ). iter () {
for right in Self :: dfs ( j , f ). iter () {
let new_node = Some ( Rc :: new ( RefCell :: new ( TreeNode {
val : 0 ,
left : left . clone (),
right : right . clone (),
})));
ans . push ( new_node );
}
}
}
f [ n as usize ] = Some ( ans . clone ());
ans
}
}
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 /**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
public class Solution {
private List < TreeNode > [] f ;
public IList < TreeNode > AllPossibleFBT ( int n ) {
f = new List < TreeNode > [ n + 1 ];
return Dfs ( n );
}
private IList < TreeNode > Dfs ( int n ) {
if ( f [ n ] != null ) {
return f [ n ];
}
if ( n == 1 ) {
return new List < TreeNode > { new TreeNode () };
}
List < TreeNode > ans = new List < TreeNode > ();
for ( int i = 0 ; i < n - 1 ; ++ i ) {
int j = n - 1 - i ;
foreach ( var left in Dfs ( i )) {
foreach ( var right in Dfs ( j )) {
ans . Add ( new TreeNode ( 0 , left , right ));
}
}
}
f [ n ] = ans ;
return ans ;
}
}