这道题是LeetCode里的第108道题。
题目描述:
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定有序数组: [-10,-3,0,5,9], 一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树: 0 / \ -3 9 / / -10 5
二分法,分治法。我们可以考虑把一个大的问题分解成为几个小的问题。
首先二分法肯定是确认的,因为要保证树结构是有序的,这个我亲自验证过了。
另外还需注意求中值 m 的时候,最好不要 (l + r) / 2 这样计算,可能会加法溢出,最安全的方法是 m = l + (r - l) / 2,就如同计算:x * x > y 不如 x > y / x 好。这些细节都有可能是面试的加分项,更厉害点可以把 m = l + (r - l) / 2 改成 m = l + ((r - l) >> 1)。
解题代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return nums == null ? null : buildTree(nums, 0, nums.length - 1);
}
private TreeNode buildTree(int[] nums, int l, int r) {
if (l > r) {
return null;
}
// int m = l + ((r - l) >> 1);
int m = l + (r - l) / 2;
TreeNode root = new TreeNode(nums[m]);
root.left = buildTree(nums, l, m - 1);
root.right = buildTree(nums, m + 1, r);
return root;
}
}
提交结果:
个人总结:
这道题我不想使用递归做,使用迭代却因为无法处理进出栈的顺序而无法完成任务。
堆栈迭代做法:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private class Node{
int low, up;
TreeNode t;
Node(int l, int p, TreeNode node){
low = l;
up = p;
t = node;
}
}
public TreeNode sortedArrayToBST(int[] nums) {
if(nums == null || nums.length == 0)return null;
// initialize
Stack<Node> stack = new Stack<Node>();
TreeNode root = new TreeNode(nums[(nums.length - 1)/2]);
Node rootNode = new Node(0, nums.length - 1, root);
stack.push(rootNode);
// iteration
while(!stack.isEmpty()) {
Node node = stack.pop();
int middle = (node.low + node.up) / 2;// cut half for [low, up]
// [low, middle - 1]
if(middle - 1 >= node.low) {
TreeNode leftnode = new TreeNode(nums[(middle-1+node.low)/2]);
node.t.left = leftnode;
Node left = new Node(node.low, middle - 1, leftnode);
stack.push(left);
}
// [middle + 1, up]
if(middle + 1 <= node.up) {
TreeNode rightnode = new TreeNode(nums[(middle+1+node.up)/2]);
node.t.right = rightnode;
Node right = new Node(middle+1, node.up, rightnode);
stack.push(right);
}
}
return root;
}
}
太强了!