来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定的有序链表: [-10, -3, 0, 5, 9],
一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:
0 / \ -3 9 / / -10 5
我们可以发现,给出的链表相当于二叉树的中序遍历,那问题就转换为根据二叉树的中序遍历还原二叉树了,问题是只知道中序遍历是没办法确定一棵二叉树的,这时我们注意到题目另一个要求,要求是高度平衡的二叉树。
那么我们就可以选链表中间位置作为二叉树的根,然后递归处理中间位置的左边、右边即可
代码实现如下:
//链表结点定义
public class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val; }
ListNode(int val, ListNode next) {
this.val = val; this.next = next; }
}
//树的节点定义
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {
}
TreeNode(int val) {
this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class Solution {
public TreeNode sortedListToBST(ListNode head) {
if (head == null) {
return null;
}
if (head.next == null) {
return new TreeNode(head.val);
}
//快慢指针找中心点,p一次走一步,q一次走两步
ListNode p = head, q = head, pre = null;
while (q != null && q.next != null) {
pre = p;
p = p.next;
q = q.next.next;
}
//至关重要,把中心点前一个节点的next至为空
pre.next = null;
//以升序链表的中间元素为根节点 , 递归构建二叉树
TreeNode treeNode = new TreeNode(p.val);
treeNode.left = sortedListToBST(head);
treeNode.right = sortedListToBST(p.next);
return treeNode;
}
}