先看96题
Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n?
Example:
Input: 3
Output: 5
Explanation:
Given n = 3, there are a total of 5 unique BST's:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
给定n,求1到n能组成一种二叉排序树
还是先晒一下自己的非常愚蠢笨重的做法(;´д`)ゞ,基本想法:根节点确定后,二叉排序数的种类=左子树种类*右子树种类。但其实这样的话,每一次递归都需要到start==end(即只有一个节点)时才结束,num(1, 1)在调用num(1, 2), num(1, 3)…都需会被调用,有大量的重复计算,下面贴上这段跑了1304ms的代码(掩面逃走)…
class Solution {
public int numTrees(int n) {
int count = 0;
for (int i = 1; i <= n; i++){
count += num(1, i-1) * num(i+1, n);
}
return count;
}
private int num(int start, int end){
int count = 0;
if (start >= end)
return 1;
else{
for (int i = start; i <= end; i++){
count += num(start, i-1) * num(i+1, end);
}
return count;
}
}
}
跑出这个时间的时候我已经脑内预演了自己砸掉电脑,收拾行李,坐上火车,回家开小卖部…,然后我在讨论区看到了这份答案
public static int numTrees(int n) {
int [] G = new int[n+1];
G[0] = G[1] = 1;
for(int i=2; i<=n; ++i) {
for(int j=1; j<=i; ++j) {
G[i] += G[j-1] * G[i-j];
}
}
return G[n];
}
什么叫差距…这踏马就叫差距!!
冷静一下,发现其实是一样的思路(是吧?),但是发帖人用数组把每一步的计算结果存起来,避免了大量的重复计算,用时0ms…想哭
最近刷题刷的有点颓,各位和我一样感觉灰心的战友们,挺住啊加油啊冲啊啊啊啊!
再被96题虐过之后,找了一篇有关动态规划的文章看了一下,终于95题自己搞出来了…
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:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
在95的基础上,96题要求记录每一种二叉排序树的结构
思路:感觉动态规划更像一种智力题…你得先找规律
规律:n=1, 二叉排序树: 1,一种
n=2,二叉排序树: 1->2,1<-2,( ->表示右子树, <- 表示左子树)
假如 n=i-1 已知,n=i 相当于在 n=i-1 的基础上,把每个 n=i-1 的二叉排序树加到根为 i 的左子树上,或者把值为 i 的节点替换每个 n= i-1 的二叉排序树的每个右子树节点,把被替换的子树整个加到 i 的左子树上。
另外因为ArrayList.add(TreeNode)是浅复制,之后修改值会影响已添加的值,所以写了个cloneTree()函数,通过new TreeNode实现深复制。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<TreeNode> generateTrees(int n) {
if (n == 0)
return new ArrayList<>();
List<TreeNode> r = new ArrayList<>();
r.add(null);
for (int i = 1; i <= n; i++){
int len = r.size();
for (int j = 0; j < len; j++) {
TreeNode rj = r.remove(0);
TreeNode cur = new TreeNode(i);
// cur做根,所有都是左子树
cur.left = cloneTree(rj);
r.add(cur);
cur = new TreeNode(i);
// cur做每棵树的最右子树
TreeNode p = rj;
if (p != null){
while (p.right != null){
cur.left = p.right;
p.right = cur;
r.add(cloneTree(rj));
p.right = cur.left;
cur.left = null;
p = p.right;
}
p.right = cur;
r.add(cloneTree(rj));
}
}
}
return r;
}
private TreeNode cloneTree(TreeNode t){
if (t == null)
return null;
TreeNode a = new TreeNode(t.val);
a.left = cloneTree(t.left);
a.right = cloneTree(t.right);
return a;
}
}