一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情。
一、题目
leetcode 有序链表转换二叉搜索树
给定一个单链表的头节点 head ,其中的元素 按升序排序 ,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差不超过 1。
示例 1:
输入: head = [-10,-3,0,5,9]
输出: [0,-3,9,-10,null,5]
解释: 一个可能的答案是[0,-3,9,-10,null,5],它表示所示的高度平衡的二叉搜索树。
示例 2:
输入: head = []
输出: []
提示:
head 中的节点数在[0, 2 * 104] 范围内
-105 <= Node.val <= 105
二、题解
需要将一个单链表转换为一个高度平衡的二叉搜索树,首先二叉搜索树定义为如果左子树不为空,那么左子树的所有节点都小于根节点,如果右子树不为空,那么右子树的所有节点都大于根节点,任意的子树也是如此。那么高度平衡的意思是二叉搜索树的左右子树的层级差不超过1。并且给定的链表按升序排序。
方法一
要构造这个二叉树首先就需要确定其根节点是什么,同时还需要高度平衡的,也就是左右两边节点数量应该差不多的。
那么我们可以找到链表的中间节点,也就是中间数,拿这个数来做二叉树的根节点,那么链表左右的节点就可以去构造左右子树,最后的二叉树高度就会平衡了。具体的先找到链表的一个中间节点node,然后把这个节点构造一个数的根节点,然后是左子树,那么对于左子树同样的就递归去构造其根节点,同时找左子树的根节点就需要链表的node节点之前的一部分链表去找;同样对于右子树也递归去构造其根节点,找右子树的根节点就需要链表的node节点之后部分节点中寻找。最后链表没有中间节点,也就是只有查询链表中只有一个节点,那么就结束递归。最后返回树节点即可。
三、代码
方法一 Java代码
class Solution {
public TreeNode sortedListToBST(ListNode head) {
return getTree(head, null);
}
public TreeNode getTree(ListNode left, ListNode right) {
if (left == right) {
return null;
}
ListNode mid = getNode(left, right);
TreeNode root = new TreeNode(mid.val);
root.left = getTree(left, mid);
root.right = getTree(mid.next, right);
return root;
}
public ListNode getNode(ListNode left, ListNode right) {
ListNode fast = left;
ListNode slow = left;
while (fast != right && fast.next != right) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
时间复杂度:O(n),需要递归构造二叉树节点以及遍历链表查询中间节点。
空间复杂度:O(n),需要构造二叉树空间以及递归栈空间。