95. Unique Binary Search Trees II
1. 题目
题目链接
Given an integer n, generate all structurally unique BST’s (binary search trees) that store values 1 … n.
Example:
Input: 3
Output:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
Explanation:
The above output corresponds to the 5 unique BST’s shown below:
2. 题目分析
这题是Unique Binary Search Trees 的升级版(可以查看我的前一篇博文()),这次不是要找给定关键字1…n来计算能创建的二叉查找树的种类,而是直接列出可以创建的所有的二叉查找树。
3. 解题思路
做过Unique Binary Search Trees的应该知道,要怎么计算它可能生成的二叉查找树,即选择1…n中的任一关键字 i 作为根节点,然后将所有关键字分成两部分[1…i-1], [i+1…n],分别将这两部分作为根节点的左子树与右子树。然后对左右子树进行如此操作,可以看出,这是一个递归的过程,但最大的问题是怎么在递归中吧节点的value进行分别存储到每一种可能列表中。一开始我是通过在方法中传递节点TreeNode,因为这是一个引用数据类型作为形参,所以在方法中做的修改,即使不returnTreeNode,在方法外还是能接收到修改。但我发现,在方法中修改引用参数中的引用类型的属性值,为什么在方法外接收不到修改的变化???
然后,实验如下:
public class TestFunctionParameter {
public static void main(String[] args) {
Node node = new Node(1);
changeFunctionParam(node);
System.out.println("修改引用参数的基本类型的值后:"+node.data);
changeFunctionParam_1(node);
System.out.printf("修改引用参数中的引用类型的属性值后:");
if (node.left != null){
System.out.println("null!");
}else{
System.out.println(node.left);
}
}
public static void changeFunctionParam(Node node){
node.data = 2;
}
public static void changeFunctionParam_1(Node node){
Node left = new Node(20);
node.left = left;
}
}
class Node{
Node left;
Node right;
int data;
public Node(int data) {
this.data = data;
}
}
然后输出结果是这个
修改引用参数的基本类型的值后:2
修改引用参数中的引用类型的属性值后:null!
经过查找资料,发现原因是:
发现方法传参的思路走不通,所以换了一个思路,通过List把节点值return回来。
4. 代码实现(java)
package com.algorithm.leetcode.dynamicAllocation;
import java.util.ArrayList;
import java.util.List;
/**
* Created by 凌 on 2019/1/27.
* 注释:95. Unique Binary Search Trees II
*/
public class GenerateTrees {
public List<TreeNode> generateTrees(int n) {
if (n <1){
return new ArrayList();
}
return generateChildrenTrees(1,n);
}
public List<TreeNode> generateChildrenTrees(int start,int end) {
List<TreeNode> treeNodeList = new ArrayList<>();
TreeNode root = null;
if (start > end){
treeNodeList.add(root);
return treeNodeList;
}
for (int i = start; i <= end; i++) {
List<TreeNode> leftNode = generateChildrenTrees(start, i - 1);
List<TreeNode> rightNode = generateChildrenTrees(i + 1, end);
for(TreeNode left : leftNode) {
for(TreeNode right : rightNode) {
root = new TreeNode(i);
root.left = left;
root.right = right;
treeNodeList.add(root);
}
}
}
return treeNodeList;
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}