输入: 升序单链表头结点 head。
要求: 将其转换成一棵高度平衡的二叉搜索树(BST)。
输出: 构造出的 BST 根节点 TreeNode*。
思路:
这题和 LC.108(有序数组转 BST)几乎是同一道题,区别只在于:这里给的是链表,不支持随机访问。
所以本解法先做一个“降维”:
-
链表转数组
- 从
head开始一路遍历,把每个节点值依次push_back到vector<int> a。 - 因为链表本身按升序排列,所以得到的数组
a也是升序。
- 从
-
数组分治构建平衡 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;
}
};

被折叠的 条评论
为什么被折叠?



