[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;

    }

}

 

你可能感兴趣的:(Binary search)