LeetCode 109 有序链表转换二叉搜索树 C++

109 有序链表转换二叉搜索树

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

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

示例:

给定的有序链表: [-10, -3, 0, 5, 9],

一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:

在这里插入图片描述

方法一

首先要了解什么是高度平衡二叉搜索树
题目已经告诉了一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1,做一个不太恰当的比喻就像一根绳子,你想让它两边长度差不多,那么你要从绳子中间将它拎起来吧,同理这点拎起来的点就是高度平衡二叉搜索树的根节点,我们要先找到它,然后将根节点的左边链表放到座左子树里,右半部分链表放进右子树里就好了。
2.如何找到根结点这里可以利用链表常见的套路快慢指针来查找,设置快慢指针都从头结点开始遍历,慢指针一次走一步,快指针一次走两步,当快指针走到头时,慢指针的位置就是链表的中点(结点个数为奇数)或是中间两个任意一个数(当结点个数为偶数时)。
3,根据根节点采取递归的思想构建左子树和右子树,给定列表中的中间元素将会作为二叉搜索树的根,该点左侧的所有元素递归的去构造左子树,同理右侧的元素构造右子树。这必然能够保证最后构造出的二叉搜索树是平衡的。
以奇数点为例看下图实例过程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上述图片来自力扣官方题解,相信看完这个动画,应该会更加了解这个流程,接下来上代码C++版本

class Solution {
    
    
public:
    TreeNode* sortedListToBST(ListNode* head) {
    
    
        return buildTree(head,nullptr);
    }
    TreeNode*buildTree(ListNode*head,ListNode*tail)
    {
    
    
        if(head==tail) return nullptr;
        ListNode*slow=head;
        ListNode*fast=head;
        while(fast!=tail&&fast->next!=tail)
        {
    
    
            slow=slow->next;
            fast=fast->next->next;

        }
        TreeNode*root=new TreeNode(slow->val);
        root->left=buildTree(head,slow);
        root->right=buildTree(slow->next,tail);
        return root;
    }
};

方法二

其核心就是将有序链表转换为数组去查找中心点,毕竟链表查找中心点要遍历,很耗费时间,而数组查找时间为O(1),找到后也采取递归思想去构建左右子树,就不展开讲解了,如果上一个方法能看懂,这个方法很容易明白
直接上代码

class Solution {
    
    
public:
    TreeNode* sortedListToBST(ListNode* head) {
    
    
        vector<int>v;
        while(head!=nullptr)
        {
    
    
            v.push_back(head->val);
            head=head->next;
        }
        return buildTree(v,0,v.size());
    }
    TreeNode*buildTree(vector<int>&v,int begin,int end)
    {
    
    
        if(begin==end) return nullptr;
        int mid=(begin+end)/2;
        TreeNode*root=new TreeNode(v[mid]);
        root->left=buildTree(v,begin,mid);
        root->right=buildTree(v,mid+1,end);
        return root;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_42076938/article/details/106663230