[LeetCode#108]Convert Sorted Array to Binary Search Tree

The problem:

Given an array where elements are sorted in ascending order, convert it to a height balanced BST.

My analysis:

The recursion is the best way to solve this kind of problem: At each step, we follow the same pattern to divide the problem into subproblems, and merge the answers together as the original problem. (divide - conqueror)
The problem's pattern is:
1. we find the mid of the given array, and set it as the current tree's root(new a node).
2. we set the left pointer to the result of tree ([low ... mid - 1]).
3. we set the right pointer to the result of tree ([mid + 1 ... high]).
4. then we return the node.

On thing we should be bery careful is the base case.
It's very easy to wrongly write the base case as:

if (low == high) {
    return TreeNode(num[low]);
}

This problem is arisen from the wrong conception that: in binary search(divide), we could always reach the (low == high) as termination condition. In fact this idea is absolutely wrong!!! That's way we use "while(low <= high)" as condition for loop in binary search.
In fact, we could not always reach "low == high", considering following cases:

ret.left = helper(num, low, mid - 1);
ret.right = helper(num, mid + 1, high);

1. num[] = [0, 1]
low = 0, high = 1, mid = (low + high) / 2 = 0.
helper (num, low, mid - 1) ===> helper(num, 0, -1); //low == high could not be used. 
helper (num, mid + 1, high) ===> helper(num, 1, 1);

2. num[] = [0, 1, 2]
low = 0, high = 1, mid = (low + high) / 2 = 1.
helper (num, low, mid - 1) ===> helper(num, 0, 0);
helper (num, mid + 1, high) ===> helper(num, 1, 1);

From aboving analysis, we could find out that, when the searched array is in odds length, we would meet "low == high".
However, when the array is in even length, we would not meet "low == high".

We could fix this problem by using "low > high" as termination condition.
For this case, we use following base case:

if (low > high) { //we use a violation as base case!!! beautiful!
    return null;
}

1. num[] = [0, 1]
low = 0, high = 1, mid = (low + high) / 2 = 0.
helper (num, low, mid - 1) ===> helper(num, 0, -1); //violation happens, return null 
helper (num, mid + 1, high) ===> helper(num, 1, 1); 
===>
low =  1, high = 1, mid = (low + high) / 2 = 1.
helper (num, low, mid - 1) ===> helper(num, 1, 0); //violation happens, return null
helper (num, mid + 1, high) ===> helper(num, 2, 1); //violation happens, return null

Thus, we could perfectly reach the right termination state!

My solution:

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode sortedArrayToBST(int[] num) {
        if (num == null || num.length == 0)
            return null;
        
        return helper(num, 0, num.length - 1);
    }
    
    public TreeNode helper(int[] num, int low, int high) {
        
        if (low > high) {
            return null;
        }
        
        int mid = (low + high) / 2;
        TreeNode ret = new TreeNode(num[mid]); //partion the num array into two part 
        ret.left = helper(num, low, mid - 1); //point the left child pointer to the left part of the tree
        ret.right = helper(num, mid + 1, high); //point the right child pointer to the right part of the tree
        
        return ret;
    }
}
原文地址:https://www.cnblogs.com/airwindow/p/4209663.html