Idiot-maker

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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);
                }
            }
        }
    }
}

 

posted on 2015-04-18 22:36  NickyYe  阅读(136)  评论(0编辑  收藏  举报