题目地址(109. 有序链表转换二叉搜索树)
https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/
题目描述
给定一个单链表的头节点 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
- 观察题目发现,升序排列的链表相当于二叉树的中序遍历,其中根节点正好处于中间节点处,由此想到快慢指针可以用于找中间节点,快指针一次前进两节点,慢指针一次前进一个节点,当快指针到达尾节点处时,慢指针恰好处于中间节点。以上思路确定根节点
- 由于二叉搜索树的左子树节点都小于根节点,右子树节点都大于根节点。链表恰好是升序排列,中间节点的左侧均小于中间节点,中间节点的右侧均大于中间节点,创建左右子树即可。
代码1
- 语言支持:JavaScript
JavaScript Code:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {ListNode} head
* @return {TreeNode}
*/
var sortedListToBST = function(head) {
if (!head) return null;
return dfs(head,null);
};
function dfs(head, tail) {
if (head == tail) {
return null;
}
let fast = head;
let slow = head;
while (fast != tail && fast.next != tail) {
fast = fast.next.next;
slow = slow.next;
}
let root = new TreeNode(slow.val);
root.left = dfs(head, slow);
root.right = dfs(slow.next, tail);
return root;
}
复杂度分析1(不太会。。。)
令 n 为链表长度。
- 时间复杂度: O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n)) 递归树的深度为 lognlogn,每一层的基本操作数为 nn,因此总的时间复杂度为O(nlogn)
- 空间复杂度: O ( l o g ( n ) ) O(log(n)) O(log(n))
思路2
空间换时间,用数组将链表存储起来