https://leetcode.com/problems/unique-binary-search-trees-ii/
Given n, generate all structurally unique BST's (binary search trees) that store values 1...n.
For example,
Given n = 3, your program should return all 5 unique BST's shown below.
1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
解题思路:
这题和 Unique Binary Search Trees 算是差不多的题目,一个要求解的数量,一个要列出所有的解。这么多题做下来,大概也知道一般求解的数量用dp,求所有的解用dfs。那么这题似乎是用dfs。
但是这题也不是传统的dfs,因为他有左右两个子树,不能通过类似单一维度的dfs来做。话说思路是知道,当根节点为i的时候,左子树由[0, i - 1]的数字构成,右子树又[i + 1, n]的数字构成。对左子树,左子树由[0, j - 1],右子树由[j + 1, i - 1]的数构成。对右子树,左子树由[i + 1, k],右子树由[k + 1, n]组成。如此递归。
对于一个left, root, right范围内的左右子树,所有可能的树是左右子树的笛卡儿积。
那么我们可以从下往上的形成所有可能的解。
/** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; left = null; right = null; } * } */ public class Solution { public List<TreeNode> generateTrees(int n) { return generate(1, n); } public List<TreeNode> generate(int left, int right) { List<TreeNode> result = new ArrayList<TreeNode>(); if(left > right) { result.add(null); return result; } for(int i = left; i <= right; i++) { List<TreeNode> leftList = generate(left, i - 1); List<TreeNode> rightList = generate(i + 1, right); for(TreeNode leftNode : leftList) { for(TreeNode rightNode : rightList) { TreeNode root = new TreeNode(i); root.left = leftNode; root.right = rightNode; result.add(root); } } } return result; } }
思路是知道,但是能写出递归的方法,我是看了别人的代码。只能说,对于递归,特别是带有返回值的递归,还是掌握的不够深刻。
http://blog.csdn.net/linhuanmars/article/details/24761437
http://www.cnblogs.com/yuzhangcmu/p/4256291.html
http://pisxw.com/algorithm/Unique-Binary-Search-Trees-II.html
https://github.com/yuzhangcmu/LeetCode/blob/master/tree/GenerateTree2.java
http://blog.sina.com.cn/s/blog_eb52001d0102v21l.html
update 2015/05/17:
http://yucoding.blogspot.jp/2013/05/leetcode-question115-unique-binary.html
这位作者很好的解释了,怎么从一般的dfs想到下面的解法,比较好。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<TreeNode> generateTrees(int n) { List<TreeNode> list = new ArrayList<TreeNode>(); dfs(1, n, list); return list; } public void dfs(int start, int end, List<TreeNode> list) { if(start > end) { list.add(null); return; } for(int i = start; i <= end; i++) { List<TreeNode> leftList = new ArrayList<TreeNode>(); dfs(start, i - 1, leftList); List<TreeNode> rightList = new ArrayList<TreeNode>(); dfs(i + 1, end, rightList); for(TreeNode left : leftList) { for(TreeNode right : rightList) { TreeNode root = new TreeNode(i); root.left = left; root.right = right; list.add(root); } } } } }