力扣109. 有序链表转换二叉搜索树(递归 + 转成数组)
https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定的有序链表: [-10, -3, 0, 5, 9],
一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
递归 + 转成数组
空间换时间
注意:BST二叉搜索树的中序遍历是升序的,它的权值必然 ≥ 所有
左子树节点的权值,≤ 所有
右子树节点的权值。
复杂度分析
时间复杂度:时间复杂度降到了 O(N) ,因为需要将链表转成数组。而取中间元素的开销变成了 O(1) 所以整体的时间复杂度降低了。
空间复杂度:因为我们利用额外空间换取了时间复杂度的降低,空间复杂度变成了 O(N),相较于之前算法的 O(logN) 有所提升,因为创建数组的开销。
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
TreeNode* sortedListToBST(ListNode* head)
{
//鲁棒性
if (head == nullptr)return nullptr;
//转换成数组
vector<int>vec;
ListNode* cur = head;
while (cur != nullptr)
{
vec.push_back(cur->val);
cur = cur->next;
}
//建树
int length = vec.size() - 1;
int mid = (length + 0) / 2;
//新节点
TreeNode* root = new TreeNode(vec[mid]);
root->left = digui(vec, 0, mid - 1);
root->right = digui(vec, mid + 1, length);
return root;
}
TreeNode* digui(vector<int> &vec, int begin, int end)
{
//递归终止
if (begin > end)
{
return nullptr;
}
int middigui = (end + begin) / 2;
//新节点
TreeNode* temp = new TreeNode(vec[middigui]);
temp->left = digui(vec, begin, middigui - 1);
temp->right = digui(vec, middigui + 1, end);
return temp;
}
};
int main()
{
ListNode head[6] = { -10,-3,-1,0,5,9 };
head[0].next = &head[1];
head[1].next = &head[2];
head[2].next = &head[3];
head[3].next = &head[4];
head[4].next = &head[5];
Solution s;
auto result = s.sortedListToBST(head);
return 0;
}