Leetcode109. 有序链表转换二叉搜索树
题目描述
/**
* 给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
* <p>
* 本题中,一个高度平衡二叉树是指一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1。
*/
思路分析
- 将有序链表转换为一棵自平衡的二叉搜索树,思路和将一个有序数组转换为一棵二叉搜索树类似
- 首先需要找到链表的中间节点,可以使用快慢指针法,即使用双指针,快指针的速度时是慢指针速度的两倍,则当快指针到达链表的末尾时,慢指针刚好指向链表的中间位置
- 记录慢指针当前所在的节点,即为二叉搜索树的根节点
- 使用分治的思想,对分割开的子链表使用递归,作为根节点的左子树和右子树,直到链表的所有节点全部使用完毕
- 源码见下
源码及分析
public TreeNode sortedListToBST(ListNode head) {
return buildTree(head, null);
}
//递归的构建一棵树
public TreeNode buildTree(ListNode left, ListNode right) {
if (left == right) {
return null;
}
//获取当前链表的中间节点
ListNode mid = getMid(left, right);
//使用当前链表中间节点的值作为二叉平衡树的根节点构建一棵新树
TreeNode root = new TreeNode(mid.val);
//递归填充子节点
root.left = buildTree(left, mid);
root.right = buildTree(mid.next, right);
return root;
}
//获取链表的中间节点,使用快慢指针法
public ListNode getMid(ListNode left, ListNode right) {
//初始让快慢指针都指向头节点
ListNode fast = left;
ListNode slow = left;
//快指针速度是慢指针速度的两倍,当快指针到达末尾时则慢指针所在位置就是链表的中间节点
while (fast != right && fast.next != right) {
fast = fast.next;
fast = fast.next;
slow = slow.next;
}
return slow;
}