zoukankan      html  css  js  c++  java
  • 109.Convert sorted list to BST

        /*
         * 109.Convert sorted list to BST 
         * 2016.12.24 by Mingyang
         * 这里的问题是对于一个链表我们是不能常量时间访问它的中间元素的。
         * 这时候就要利用到树的中序遍历了,按照递归中序遍历的顺序对链表结点一个个进行访问,而我们要构造的二分查找树正是按照链表的顺序来的。
         * 思路就是先对左子树进行递归
         * 然后将当前结点作为根,迭代到下一个链表结点,最后在递归求出右子树即可。整体过程就是一次中序遍历,时间复杂度是O(n),空间复杂度是栈空间O(logn)
         * 但是我没用上面的二分查找,用的是快慢节点recursive来做,所以这么做就有缺陷:
         */
         public TreeNode sortedListToBST(ListNode head) {
                if(head == null)
                    return null;
                ListNode fast = head;
                ListNode slow = head;
                ListNode prev =null; 
                while(fast != null && fast.next != null)
                {
                    fast = fast.next.next;
                    prev =slow;
                    slow=slow.next;
                }
                TreeNode root = new TreeNode(slow.val);
                if(prev != null)
                    prev.next = null;
                else
                    head  = null;
                root.left = sortedListToBST(head);
                root.right = sortedListToBST(slow.next);
                return root;
            }
        /*
         * 上面做法的缺陷在哪呢,这个跟Convert Sorted Array to Binary Search Tree比较近似,
         * 区别是元素存储的数据结构换成了链表,不过引入了一个重要的问题,就是链表的访问不是随机存取的,
         * 也就是不是O(1)的,如果每次去获取中点,然后进行左右递归的话,我们知道得到中点是O(n/2)=O(n)的,
         * 如此递推式是T(n) = 2T(n/2)+n/2,复杂度是O(nlogn),并不是线性的,所以这里我们就得利用到树的中序遍历了,
         * 按照递归中序遍历的顺序对链表结点一个个进行访问,而我们要构造的二分查找树正是按照链表的顺序来的。
         * 如此就能按照链表的访问顺序来构造,不会因此而增加找中间结点的复杂度。
         * 记住每次都需要node往后移动一位
         */
         private ListNode node;
         public TreeNode sortedListToBST2(ListNode head) {
             if(head == null){
                 return null;
             }
             int size = 0;
             ListNode runner = head;
             node = head;
             while(runner != null){
                 runner = runner.next;
                 size ++;
             }
             return inorderHelper(0, size - 1);
         }
         public TreeNode inorderHelper(int start, int end){
             if(start > end){
                 return null;
             }
             int mid = start + (end - start) / 2;
             TreeNode left = inorderHelper(start, mid - 1);
             TreeNode treenode = new TreeNode(node.val);
             treenode.left = left;
             node = node.next;//第一次访问到这就是左边已经到头了,才会访问到node节点
             TreeNode right = inorderHelper(mid + 1, end);
             treenode.right = right;
             return treenode;
         }
  • 相关阅读:
    ueditor 后端配置项没有正常加载,上传插件不能正常使用 UTF8 PHP
    dedecms 后台栏目全部展开 包括三级栏目
    修改DedeCMS图片上传路径命名规则的具体方法步骤
    dedecms织梦副栏目名称和链接调用
    当位于顶级栏目显示下级栏目,当位于二级栏目显示同级栏目,当位于三级目录,显示上级栏目
    织梦多个栏目arclist调用副栏目不显示的解决办法
    PL/SQL连接64位Oracle配置方法
    U盘分区之后如何恢复
    Myeclipse 的使用随笔
    eclipse和myeclipse的差别问题
  • 原文地址:https://www.cnblogs.com/zmyvszk/p/5504443.html
Copyright © 2011-2022 走看看