给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
题解(一):将有序链表转换为二叉搜索树,其实就是将有序链表不断进行二分法二分的过程,其中,二分后的左半部分子链表的最中间链表结点的结点值是当前树结点的左结点的结点值,右半部分子链表的最中间链表结点的结点值是当前树结点的右节点的结点值。按照上述规则,我们只需要不断二分链表即可
class Solution {
TreeNode headNode=new TreeNode();
public TreeNode sortedListToBST(ListNode head) {
if(head==null)
return null;
ListNode end=head;
while(end!=null)
end=end.next;
return binaryCreate(head,end);
}
//对链表进行二分,同时构造二叉搜索树
private TreeNode binaryCreate(ListNode start,ListNode end){
if(start==end)
return null;
ListNode mid=findMid(start,end);
TreeNode node=new TreeNode(mid.val);
node.left=binaryCreate(start,mid);
node.right=binaryCreate(mid.next,end);
return node;
}
//找到链表的中间结点
private ListNode findMid(ListNode start,ListNode end){
ListNode left=start,right=start;
while(right!=end&&right.next!=end){
right=right.next;
right=right.next;
left=left.next;
}
return left;
}
}
题解(二):中序遍历逆构造,我们知道将一颗二叉搜索树进行中序遍历可以得到升序排列的有序数组集,同样,我们有了有序链表,就可以逆构造出一颗二叉搜索树
class Solution {
ListNode headNode;
public TreeNode sortedListToBST(ListNode head) {
headNode=head;
if(head==null)
return null;
ListNode end=head;
int length=0;
while(end!=null){
end=end.next;
length++;
}
return midDFS(0,length-1);
}
private TreeNode midDFS(int start,int end){
if(end<start)
return null;
int mid=(start+end)/2;
TreeNode node=new TreeNode();
node.left=midDFS(start,mid-1);
node.val=headNode.val;
headNode=headNode.next;
node.right=midDFS(mid+1,end);
return node;
}
}