有序数组和有序链表转换成AVL树

有序数组转换成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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

有序链表转换成AVL树

给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:
在这里插入图片描述
方法一:快慢指针找中间节点
上一题我们可以通过下标访问一下准确确定有序序列的中间,链表怎么找中间节点,或许你会说快慢指针。那我们是需要递归去深度遍历,那每次递归都需要快慢指针去遍历找中间节点,获取中间节点 O ( N ) O(N) 。整体的时间复杂度是 O ( N l o g N ) O(NlogN) ,空间复杂度是 O ( l o g N ) 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;
    }
};
发布了139 篇原创文章 · 获赞 55 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Vickers_xiaowei/article/details/102532237