- 有序链表转换二叉搜索树
本题思路不难,由于链表本身已经有序了,根据二叉搜索树的性质,每次在当前的链表找到中点作为当前树的根节点,再将链表分割并递归构造子树。
同时在寻找链表中点的时候采用快慢指针提高速度。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
TreeNode* T = buildTree(head);
return T;
}
TreeNode* buildTree(ListNode* head){
if(!head){
return NULL;
}
if(!head->next){
TreeNode* T = new TreeNode(head->val);
return T;
}
ListNode* mid = findMid(head);
TreeNode* T = new TreeNode(mid->val);
ListNode* p = head;
// NULL放在右边进行比较,不能作为一个表达式放在左边比较
while(p->next!=mid){
p = p->next;
}
p->next = NULL;
ListNode* r = mid->next;
T->left = buildTree(head);
if(r){
T->right = buildTree(r);
}
return T;
}
ListNode* findMid(ListNode* head){
ListNode* slow = head;
ListNode* fast = head;
while(fast!=NULL && fast->next!=NULL){
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
};
- 时间复杂度: o ( n l o g n ) o(nlogn) o(nlogn)按照常规的分治算法复杂度来计算
- 空间复杂度: o ( n ) o(n) o(n)每次递归调用产生一个节点,一共n个节点,每次递归调用为常数级空间复杂度。