Unique Binary Search Trees II

来源:互联网 发布:淘宝otc货到付款 编辑:程序博客网 时间:2024/04/30 07:43

这个题比想象的要难一点,主要是费劲,寻找一种合适的遍历所有可能结果的方法。没想到我前后相隔两次做居然用了两种截然不同的方法。


方法1. 思路比较好想:自顶向下,先定head是什么,根据BST的定义,左边一定比head小,右边一定比head大。

那因此可以构成一组画面,一个从1到n排序好的list,先选定任意一个值提起来作为head。当前的状态已经是一组解了。但是没有结束,提起来的head把原来的list分成了两个子list。

对每个子list遍历所有可能,Done。


public class Solution {     ArrayList<TreeNode> reslist=new ArrayList<TreeNode>();    int tn;    public ArrayList<TreeNode> buildTree(List<Integer> list){        ArrayList<TreeNode> clist=new ArrayList<TreeNode>();        if(list==null||list.size()==0)            return clist;        for(int i=0;i<list.size();i++){            List<Integer> l1=list.subList(0,i);            List<Integer> l2=list.subList(i+1,list.size());            ArrayList<TreeNode> tl1=buildTree(l1);            if(tl1.size()==0)tl1.add(null);            ArrayList<TreeNode> tl2=buildTree(l2);            if(tl2.size()==0)tl2.add(null);            for(TreeNode t1:tl1)                for(TreeNode t2:tl2){                     TreeNode thead=new TreeNode(list.get(i));                     thead.left=t1;                     thead.right=t2;                     clist.add(thead);                }        }        return clist;    }    public ArrayList<TreeNode> generateTrees(int n) {        if(n==0){            reslist.add(null);            return reslist;        }        ArrayList<Integer> nums=new ArrayList<Integer>();        tn=n;        for(int i=1;i<=n;i++)            nums.add(i);        return buildTree(nums);    }}



这是我第一次的思路。

总体而言,第一次的思路是仔细寻找了n=3时解的规律得到的,虽然最后是递归的遍历,但主体思想不是递归的思想。


思路2:第二个思路是刚写出来的,代码比第一个要长。但第二个思路是完全基于递推的,那就是我的n=3的解是怎么通过n=2的解得到的呢?

仔细看一下n=2只有2个解: 1#2 以及 21 而后呢?

21只能演化出两组解,即32#1以及213,仔细琢磨就会发现,分别是把新来的元素3夹在了头节点,以及头结点的右结点上。


1#2呢?生成了3组解,类似的分别是把3夹在了头结点(31#2),头结点的右节点(1#32)以及头.right.right(1#2#3).


那么就有思路了,用两个list分别来做n=k的解和n=k+1的解。每次基于n=k的解生成n=k+1的解。Done!

代码长了一半,速度略比思路1快。


public class Solution {    ArrayList<TreeNode> tmplist = new ArrayList<TreeNode>();ArrayList<TreeNode> reslist = new ArrayList<TreeNode>();public ArrayList<TreeNode> generateTrees(int n) {if (n == 0){            tmplist.add(null);   return tmplist;}TreeNode h1 = new TreeNode(1);tmplist.add(h1);for (int i = 2; i <= n; i++) {for (TreeNode node : tmplist)addnum(i, node);tmplist = reslist;reslist = new ArrayList<TreeNode>();}return tmplist;}public void addnum(int v, TreeNode head) {TreeNode p = head;TreeNode newNode = new TreeNode(v);newNode.left = head;reslist.add(newNode);int level = 0;while (p != null) {reslist.add(copyAndAdd(head, null, level, v));level++;p = p.right;}}public TreeNode copyAndAdd(TreeNode head, TreeNode dhead, int level, int v) {if (dhead == null && head != null)dhead = new TreeNode(head.val);if (head.left != null) {TreeNode nleft = new TreeNode(head.left.val);dhead.left = nleft;copyAndAdd(head.left, nleft, -1, 0);}if (head.right != null) {TreeNode nright = new TreeNode(head.right.val);if (level == 0) {TreeNode tnode = new TreeNode(v);dhead.right = tnode;tnode.left = nright;} elsedhead.right = nright;copyAndAdd(head.right, nright, level - 1, v);} else if (level == 0) {TreeNode tnode = new TreeNode(v);dhead.right = tnode;}return dhead;}}



很奇妙,用的递推的思路,却没用递归的方法。


0 0