LeetCode-108-数组转AVL
1. 题目描述
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。1
2
3
4
5
6
7
8
9给定有序数组: [-10,-3,0,5,9],
一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
2. 思路
可以很明显的知道,一棵AVL的中序遍历就是原排序数组了,所以这个题相当于就是中序遍历的逆过程,类似二分查找,然后递归的构造二叉树即可,这个题也是easy题,不过还是想记录一下,因为之前刷的题基本都是数组/链表
之类的,涉及到树的比较少,最近有时间我也会复习一下AVL相关的内容,并整理出一篇博客出来,敬请期待…
3. 代码
1 | /** |
4. 相似题
- 109.有序链表转平衡二叉树
这个题和108题其他条件一模一样,区别就是数组换成了链表,大致有两种解法:
- 用快慢指针不断找到链表的中间结点,然后再在左边和右边各自递归处理。时间复杂度为
O(N*logN)
,空间复杂度为O(logN)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30public TreeNode sortedListToBST(ListNode head) {
// 空链表
if (head == null)
return null;
// 只有一个元素
if (head.next == null)
return new TreeNode(head.val);
ListNode fast = head;
ListNode slow = head;
ListNode prev = head;
// slow指向中间结点,fast指向最后一个结点
while (fast!=null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
// 让prev指针指向slow的前一个
while (prev.next != slow) {
prev = prev.next;
}
// 让原链表断成3部分,中间那个作为根节点
TreeNode mid = new TreeNode(slow.val);
prev.next = null;
ListNode rightList = slow.next;
mid.left = sortedListToBST(head);
mid.right = sortedListToBST(rightList);
return mid;
} - 先将链表中的所有元素记录用一个数组保存起来(这是为了到时候找中间结点是不要每次都去扫描链表),一种空间换时间的方式。
时间复杂度为O(N)
,空间复杂度为O(N)