天天看點

leetcode:Unique Binary Search Trees II問題描述:問題分析

問題描述:

Given an integer 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
      

原問題連結:https://leetcode.com/problems/unique-binary-search-trees-ii/

問題分析

遞歸法

  這個問題在之前的讨論裡已經列出了它的基本遞歸屬性。對于給定的n個元素來說,它構成的子樹數量是類似于如下的關系:f(n) = sum(f(i) * f(n - i - 1)) (i = 1, ... n)

  在這裡,就是需要将這個描述的遞歸關系轉化成代碼。從實作細節的角度來說,我們這裡定義一個generateTree(int start, int end) 的遞歸函數。start, end分别表示構造樹的起始數和結尾數。在start > end的時候,我們傳回null作為它的結果集。否則的情況下針對(start, i - 1) (i + 1, end)來遞歸的構造以i節點為根的數,并将根節點加入到結果集中。

  詳細的代碼實作如下:

/**
 * 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) {
        if(n == 0) return new ArrayList<TreeNode>();
        return generateTrees(1, n);
    }

    List<TreeNode> generateTrees(int start, int end) {
        List<TreeNode> result = new ArrayList<TreeNode>();
        if(start > end) {
            result.add(null);
            return result;
        }
        for(int i = start; i <= end; i++) {
            List<TreeNode> leftSubTrees = generateTrees(start, i - 1);
            List<TreeNode> rightSubTrees = generateTrees(i + 1, end);
            for(TreeNode left : leftSubTrees) {
                for(TreeNode right : rightSubTrees) {
                    TreeNode root = new TreeNode(i);
                    root.left = left;
                    root.right = right;
                    result.add(root);
                }
            }
        }
        return result;
    }
}
           

動态規劃法

   除了上述的遞歸法,我們也可以利用前面遞歸的條件來用動态規劃法來做。主要的思路也近似,就是用一個List[]數組或者清單來儲存前面的結果,針對0個元素傳回一個空的list。

  詳細的代碼實作如下:

/**
 * 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) {
        if(n == 0) return new ArrayList<TreeNode>();
        List<TreeNode>[] list = new List[n + 1];
        list[0] = new ArrayList<>();
        list[0].add(null);
        for(int i = 1; i <= n; i++) {
            list[i] = new ArrayList<>();
            for(int j = 0; j < i; j++) {
                for(TreeNode lNode: list[j])
                    for(TreeNode rNode : list[i - j - 1]) {
                        TreeNode node = new TreeNode(j + 1);
                        node.left = lNode;
                        node.right = clone(rNode, j + 1);
                        list[i].add(node);
                    }
            }
        }
        return list[n];
    }
    
    private TreeNode clone(TreeNode node, int offset) {
        if(node == null) return null;
        TreeNode cloneNode = new TreeNode(node.val + offset);
        cloneNode.left = clone(node.left, offset);
        cloneNode.right = clone(node.right, offset);
        return cloneNode;
    }
    
}