Unique Binary search Tree

Problem

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

Solution 1

using recursion,

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode(int x) { val = x; }
  8. * }
  9. */
  10. public class Solution {
  11. public List<TreeNode> generateTrees(int n) {
  12. List<TreeNode> result = new ArrayList<TreeNode>();
  13. if(n==0){
  14. return result;
  15. }
  16. return buildTrees(1,n);
  17. }
  18. public List<TreeNode> buildTrees(int start, int end){
  19. List<TreeNode> result = new ArrayList<TreeNode>();
  20. if(start>end ){
  21. result.add(null);
  22. return result;
  23. }
  24. List<TreeNode> rightTrees = new ArrayList<TreeNode>();
  25. List<TreeNode> leftTrees = new ArrayList<TreeNode>();
  26. // pick up a root
  27. for(int i = start; i <= end; i++){
  28. // since i is root, left tree would be from start -> i-1
  29. leftTrees = buildTrees(start, i-1);
  30. // right trees would be from i+1 to end
  31. rightTrees = buildTrees(i+1,end);
  32. // generate trees
  33. for(TreeNode leftTree : leftTrees){
  34. for(TreeNode rightTree: rightTrees){
  35. TreeNode tree = new TreeNode(i);
  36. tree.left = leftTree;
  37. tree.right = rightTree;
  38. result.add(tree);
  39. }
  40. }
  41. }
  42. return result;
  43. }
  44. }

the result :

notice the above solution doesn’t use memorization

Solution 2 (with memorization)

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode(int x) { val = x; }
  8. * }
  9. */
  10. public class Solution {
  11. public List<TreeNode> generateTrees(int n) {
  12. List<TreeNode> result = new ArrayList<TreeNode>();
  13. if(n==0){
  14. return result;
  15. }
  16. return buildTrees(1,n);
  17. }
  18. public List<TreeNode> buildTrees(int start, int end){
  19. List<TreeNode> result = new ArrayList<TreeNode>();
  20. Map<String,List<TreeNode>> hashMap = new HashMap<>();
  21. StringBuilder sb = new StringBuilder();
  22. sb.append(start).append("-").append(end);
  23. if(hashMap.get(sb.toString())!=null){
  24. return hashMap.get(sb.toString());
  25. }
  26. if(start>end ){
  27. result.add(null);
  28. return result;
  29. }
  30. List<TreeNode> rightTrees = new ArrayList<TreeNode>();
  31. List<TreeNode> leftTrees = new ArrayList<TreeNode>();
  32. // pick up a root
  33. for(int i = start; i <= end; i++){
  34. // since i is root, left tree would be from start -> i-1
  35. leftTrees = buildTrees(start, i-1);
  36. // right trees would be from i+1 to end
  37. rightTrees = buildTrees(i+1,end);
  38. // generate trees
  39. for(TreeNode leftTree : leftTrees){
  40. for(TreeNode rightTree: rightTrees){
  41. TreeNode tree = new TreeNode(i);
  42. tree.left = leftTree;
  43. tree.right = rightTree;
  44. result.add(tree);
  45. }
  46. }
  47. }
  48. hashMap.put(sb.toString(),result);
  49. return result;
  50. }
  51. }

I use sart - end as key, List<TreeNode> as values to memorize the results

but the performance is even worse. I believe this is caused by the small number of test cases.

About jsdom

leading software engineer
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a comment