问题描述 链接到标题

109. 有序链表转换二叉搜索树 (Medium)

给定一个单链表的头节点 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 * 10⁴] 范围内
  • -10⁵ <= Node.val <= 10⁵

解题思路 链接到标题

首先,如果将链表换成数组,可以很方便地在 $O(n)$ 时间内完成,然后由于链表无法像数组那样在 $O(1)$ 时间内实现随机访问,因此不能套用数组的思路。

我们首先要想到,对二叉搜索树进行中序遍历,就能得到一个升序链表,那么我们也可以通过一个类似中序遍历的过程,得到二叉搜索树。即先计算左子结点,根结点就是当前遍历到的链表结点,然后计算右子结点。

代码 链接到标题

class Solution {
  public:
    TreeNode *dfs(int l, int r, ListNode **head) {
        if (l >= r) {
            return nullptr;
        }
        int mid = l + (r - l) / 2;
        TreeNode *left = dfs(l, mid, head);
        TreeNode *root = new TreeNode((*head)->val);
        root->left = left;
        *head = (*head)->next;
        root->right = dfs(mid + 1, r, head);
        return root;
    }
    TreeNode *sortedListToBST(ListNode *head) {
        // 牢记,二叉搜索树的中序遍历结果是一个升序数组
        ListNode *tail = head;
        int cnt = 0;
        while (tail != nullptr) {
            ++cnt;
            tail = tail->next;
        }
        return dfs(0, cnt, &head);
    }
};