108.有序数组转换成AVL树
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
联想:二分思想、归并、深度优先。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
return dfs(nums,0,nums.size()-1);
}
TreeNode* dfs(vector<int>& nums,int left,int right)
{
if(left>right) return nullptr;
int mid=(left+right)/2;
TreeNode* node=new TreeNode(nums[mid]);
node->left=dfs(nums,left,mid-1);
node->right=dfs(nums,mid+1,right);
return node;
}
};
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
109.有序链表转换成AVL树
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
方法一:快慢指针找中间节点
上一题我们可以通过下标访问一下准确确定有序序列的中间,链表怎么找中间节点,或许你会说快慢指针。那我们是需要递归去深度遍历,那每次递归都需要快慢指针去遍历找中间节点,获取中间节点
O
(
N
)
O(N)
O(N)。整体的时间复杂度是
O
(
N
l
o
g
N
)
O(NlogN)
O(NlogN),空间复杂度是
O
(
l
o
g
N
)
O(logN)
O(logN)。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for a binary tree node.
* 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;
if(head->next==nullptr) return new TreeNode(head->val);
ListNode*fast=head,*slow=head,*slow_pre=nullptr;
while(fast!=nullptr&&fast->next!=nullptr)
{
slow_pre=slow;
slow=slow->next;
fast=fast->next->next;
}
TreeNode*node=new TreeNode(slow->val);
if(slow_pre!=nullptr) slow_pre->next=nullptr;
node->left=sortedListToBST(head);
node->right=sortedListToBST(slow->next);
return node;
}
};
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
方法二:以空间换时间
可以直接将链表存储到数组中,方便获取中间节点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
vector<int> vec;
ListNode*cur=head;
while(cur!=nullptr)
{
vec.push_back(cur->val);
cur=cur->next;
}
return dfs(vec,0,vec.size()-1);
}
TreeNode* dfs(vector<int>& nums,int left,int right)
{
if(left>right) return nullptr;
int mid=(left+right)/2;
TreeNode* node=new TreeNode(nums[mid]);
node->left=dfs(nums,left,mid-1);
node->right=dfs(nums,mid+1,right);
return node;
}
};
中序遍历模拟
中序遍历二叉搜索树结果正好为升序。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
ListNode*cur;
public:
TreeNode* sortedListToBST(ListNode* head) {
int len=find_list_size(head);
cur=head;
return inorder_dfs(0,len-1);
}
int find_list_size(ListNode* head)
{
int r=0;
while(head)
{
r+=1;
head=head->next;
}
return r;
}
TreeNode* inorder_dfs(int left,int right)
{
if(left>right) return nullptr;
int mid=(left+right)/2;
TreeNode* left_tree=inorder_dfs(left,mid-1);
TreeNode* node=new TreeNode(cur->val);
node->left=left_tree;
cur=cur->next;
node->right=inorder_dfs(mid+1,right);
return node;
}
};