/*
         * julia's comment:
         * 1. It takes some time to do calculation of index, length of subtree.
         * This should be addressed in a simple way, maybe, 1-2 minutes.
         *
         * Julia found out that code needs to be worked on, more simple as blog:
         * http://blog.csdn.net/linhuanmars/article/details/23904883
         *
         * 2. Better solution is written called sortedListToBST_B
         */
        public static TreeNode sortedListToBST(ListNode head, int len)
        {
            if (len == 0) return null;

            if (len == 1) return
                new TreeNode (head.val);

            // put all calculations here - think about how to spend shortest time on the calculation
            int rootIndex    = len / 2 ;          // starting from 0,
            int rightTreeHeadIndex = len /2 + 1;  // example: len is even, 1, 2, 3, 4 four node
                                                  // left tree, 1, 2, then, root index:

            int leftTreeLen  = len / 2;        //
            int rightTreeLen = len - len/2 -1; // leftTreeLen + rightTreeLen + 1 = len;
                                               // len can be even or odd, so len%2 can be 1 or 0

            ListNode nthNode = nth_node(head, rootIndex);

            TreeNode root = new TreeNode(nthNode.val);   // Julia's comment: cost of calculation: O(n/2) ,
                                                         // go through the list node one by one starting from head.
                                                         // how many times: O(log n), height of tree
                                                         // time complexity: O(n logn)
                                                         // if the root node can be random accessed like array, hashmp, O(1)
                                                         // then, this algorithm will not be best in time complexity.
                                                         // this should be considered when you choose the algorithm,
                                                         // this is called top-down

            root.left = sortedListToBST(head, leftTreeLen);

            ListNode secondHalf = nth_node(head, rightTreeHeadIndex);
            root.right = sortedListToBST(secondHalf, rightTreeLen);

            return root;
        }
 /*
  *
  * reference:
  * https://github.com/soulmachine/leetcode
  *
  * 自顶向下,时间复杂度O(n^2),空间复杂度O(logn)
  *
  * Julia's comment:
  *
  * 1. put my understanding next to the source code;
  * 2. Try to cut the time to do calculation, pay attention to len%/2, which may be 0 or 1
  * 3. Pass online judge  (Try 3 times, over 10 minutes to make the calculation correct!  August 25, 2015)
  *    the original book's calculation could not pass online judge)
  *    Get experience to handle the divide and conquer, calculation.
  *
  *  32 / 32 test cases passed.
     Status: Accepted
     Runtime: 172 ms
  *
  */
 public static TreeNode sortedListToBST(ListNode head)
 {
     return sortedListToBST(head, listLength(head));
 }
        private static int listLength(ListNode node)
        {
            int n = 0;
            while (node != null)
            {
                ++n;
                node = node.next;
            }

            return n;
        }
        private static ListNode nth_node(ListNode node, int n)
        {
            while (n > 0)
            {
                node = node.next;

                n--;
            }

            return node;
        }
        /*
         * Julia's comment:
         * Action Item: make the calculation to minimum, less error-prone.
         * 1. put all calculations here - think about how to spend shortest time on the calculation
           2. len /2 only shows once, all other, use m
         * 3. Julia needs to learn how to use abstract symbol
         * 4. Try to make the code look simple, testable, maintainable.
         */
        public static TreeNode sortedListToBST_B(ListNode head, int len)
        {
            if (len == 0) return null;

            if (len == 1) return
                new TreeNode(head.val);

            int m = len / 2;           // root index,
            int r_start = m + 1;       // right sub tree start position, do not go to detail: even, odd, waste time

            int l_Len = m;             // left subtree length
            int r_len = len - m - 1;   // right sub tree length

            ListNode nthNode = nth_node(head, m);

            TreeNode root = new TreeNode(nthNode.val);  // each divide and conquer, O(1) calculation to get the root index.

            root.left = sortedListToBST(head, l_Len);

            ListNode secondHalf = nth_node(head, r_start);
            root.right = sortedListToBST(secondHalf, r_len);

            return root;
        }