题目
给定一个有序整数数组,元素各不相同且按升序排列,编写一个算法,创建一棵高度最小的二叉搜索树。
示例:
给定有序数组: [-10,-3,0,5,9],
一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
解题思路
1.递归(或者DFS)
思路:
- 因为给定的是一个有序的数组,因此对应中位数则在有序数组的中间位置。
- 每次取出中位数,并将数组一分为二,分别作为左子树和右子树进行递归的递操作
- 当数组长度为0(左右指针l>r)则说明已经切分到没得分了,那么就给当前节点赋值null并返回
代码:
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public class Test {
public static void main(String[] args) {
int[] arr = {-10, -3, 0, 5, 9};
sortedArrayToBST(arr);
}
public static TreeNode sortedArrayToBST(int[] nums) {
return createTree(nums, 0, nums.length - 1);
}
public static TreeNode createTree(int[] nums, int l, int r) {
if (l > r) {
return null;
}
int mid = l + (r - l) / 2;
TreeNode head = new TreeNode(nums[mid]);
head.left = createTree(nums, l, mid - 1);
head.right = createTree(nums, mid + 1, r);
return head;
}
}
性能:
2.使用BFS
思路:
- 这个也是一样,把数组不停的分为两部分,并分别将两个数组的对应下标保存在队列中,
- 还有就是讲当前操作节点保存到队列中(add两次…不然出一次就没了),然后不停的出队,创建结点。
代码:
public TreeNode sortedArrayToBST(int[] num) {
if (num.length == 0)
return null;
Queue<int[]> rangeQueue = new LinkedList<>();
Queue<TreeNode> nodeQueue = new LinkedList<>();
int lo = 0;
int hi = num.length - 1;
int mid = (lo + hi) >> 1;
TreeNode node = new TreeNode(num[mid]);
rangeQueue.add(new int[]{lo, mid - 1});
rangeQueue.add(new int[]{mid + 1, hi});
nodeQueue.add(node);
nodeQueue.add(node);
while (!rangeQueue.isEmpty()) {
int[] range = rangeQueue.poll();
TreeNode currentNode = nodeQueue.poll();
lo = range[0];
hi = range[1];
if (lo > hi) {
continue;
}
mid = (lo + hi) >> 1;
int midValue = num[mid];
TreeNode newNode = new TreeNode(midValue);
if (midValue > currentNode.val)
currentNode.right = newNode;
else
currentNode.left = newNode;
if (lo < hi) {
rangeQueue.add(new int[]{lo, mid - 1});
rangeQueue.add(new int[]{mid + 1, hi});
nodeQueue.add(newNode);
nodeQueue.add(newNode);
}
}
return node;
}