LC.109 | 有序链表转换二叉搜索树 | 树 | 先转数组再分治建树(同 LC.108)

输入: 升序单链表头结点 head

要求: 将其转换成一棵高度平衡的二叉搜索树(BST)。

输出: 构造出的 BST 根节点 TreeNode*


思路:

这题和 LC.108(有序数组转 BST)几乎是同一道题,区别只在于:这里给的是链表,不支持随机访问。

所以本解法先做一个“降维”:

  1. 链表转数组

    • head 开始一路遍历,把每个节点值依次 push_backvector<int> a
    • 因为链表本身按升序排列,所以得到的数组 a 也是升序。
  2. 数组分治构建平衡 BST(LC.108 同款)

    • 递归函数 build(a, l, r):用数组区间 [l, r] 构造一棵平衡 BST 并返回根。
    • 每次取 mid 为根节点,让左右区间分别递归构造左右子树:
      • root->left = build(a, l, mid - 1)
      • root->right = build(a, mid + 1, r)
    • 取中点能让左右子树规模尽量接近,从而保证“高度平衡”。

复杂度:

  • 时间复杂度:O(N)
    • 链表遍历转数组一次 O(N),建树每个元素用一次 O(N)。
  • 空间复杂度:O(N)
    • 需要数组 a 存下所有节点值;递归栈为 O(log N)。

class Solution {
public:
    TreeNode* sortedListToBST(ListNode* head) {
        vector<int> a;

        while (head != nullptr) {
            a.push_back(head->val);
            head = head->next;
        }

        return build(a, 0, (int)a.size() - 1);
    }

private:
    TreeNode* build(const vector<int>& a, int l, int r) {
        if (l > r) {
            return nullptr;
        }

        int mid = l + (r - l) / 2;

        TreeNode* root = new TreeNode(a[mid]);

        root->left = build(a, l, mid - 1);
        root->right = build(a, mid + 1, r);

        return root;
    }
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值