LeetCode109题: 有序链表转换二叉搜索树
题目说明:
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例1:
给定的有序链表: [-10, -3, 0, 5, 9],
一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
问题分析:
给定链表是一个有序链表,链表结点值从头结点开始向后增加,根据平衡二叉树的定义规则,满足左右子树高度差之不大于1,该二叉树中序遍历的结果是节点值的自增排序。
考虑:寻找链表中的中间节点,作为二叉树根节点,将链表分为前后两个子链表,分别放入二叉树的左右子树,在左右子树内部做相同的操作,因此考虑使用递归的方法实现。
注意:链表中节点个数有奇数个和偶数个两种情况,奇数个时,前后子链表节点数相同,形成平衡二叉树之间高度差不会大于1;偶数个时,前后子链表节点数差1个,根据平衡二叉树特点,满足平衡条件下,相差1个节点,高度之差不会超过1。
省略输入、输出、链表定义和二叉树定义,直接给出算法求解部分如下:
class Solution {
//找出中间节点,进行划分左右子树,递归
ListNode globalHead;
public TreeNode sortedListToBST(ListNode head) {
globalHead=head;
int length=getLength(head);
return buildTree(0,length-1);
}
//统计节点个数
public int getLength(ListNode head) {
int ans=0;
while (head!=null) {
ans++;
head=head.next;
}
return ans;
}
public TreeNode buildTree(int left,int right) {
//区间没有节点,不构成二叉树
if (left>right) {
return null;
}
//划分两个子表,递归构建左右子树
int mid=(left+right+1)/2;
TreeNode root=new TreeNode();
root.left=buildTree(left,mid-1);
root.val=globalHead.val;
globalHead=globalHead.next;
root.right=buildTree(mid+1,right);
return root;
}
}