【LeetCode】convert-sorted-link-to-binary-search-tree & convert-sorted-array-to-binary-search-tree

题干

Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.

convert-sorted-array-to-binary-search-tree

Given an array where elements are sorted in ascending order, convert it to a height balanced BST.

问题一:把从小到大排序的单链表转换成平衡二叉搜索树。

问题二:把从小到大排序的vector转换成平衡二叉搜索树。

数据结构

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

解题思路

问题一

本题主要分两步,分治和递归。由于是二叉搜索树,故排序单链表的值是左半边为左子树,右半边为右子树,具体步骤如下:一,每次找到链表的中间结点,即达到了分治的效果;二,把链表值赋给树结点,并且组成树。

问题二

与问题一类似,由于用了vector,可以使用下标,则可以更佳简单的找到中点进行分治。

参考代码

问题一:

class Solution {
public:
    TreeNode *sortedListToBST(ListNode *head) {
        if (head==NULL)
            return NULL;
        TreeNode *root1=new TreeNode(head->val);
        if (head->next==NULL)
            return root1;
        ListNode *mid=head,*end=head,*premid=NULL;
        while(end!=NULL&&end->next!=NULL)//找到链表中间结点,达到分治的效果
        {
            premid=mid;
            mid=mid->next;
            end=end->next->next;
        }
        TreeNode *root=new TreeNode(mid->val);//新结点初始化
        premid->next=NULL;
        root->left=sortedListToBST(head);//用premid左半边构建左子树
        root->right=sortedListToBST(mid->next);//用premid右半边构建右子树构建
        return root;
    }

};

问题二:

/*class Solution {
public:
    TreeNode *sortedArrayToBST(vector<int> &num) {
        if (num.size()==0)
            return  NULL;
        return BST(0, int(num.size()-1), num);

    }

    TreeNode *BST(int head,int end,vector<int> &num)
    {
        if (head<=end)
        {
            int mid=(end+head)/2+(head + end)% 2;//(*)找到中间点
            TreeNode *root=new TreeNode(num[mid]);//初始化新结点
            root->left=BST(head,mid-1,num);//构建左子树
            root->right=BST(mid+1, end,num);//构建右子树
            return root;//返回当前结点
        }
        return  NULL;//如果head>end的话就不需要建立新结点
    }

};

方法讨论

两个题类似,都是分治和递归的思想。

易错点

对于注释中(*)的部分,mid的赋值有一定的讲究。最常可能出现int mid=(end+head)/2;的赋值,但是这个是有错误的,当只有两个数据的时候,mid就会等于0,第一次左子树递归的时候会出现head>end,于是第二个值就会赋给右子树,例如本来结果应该是{1,3},这样写结果就变成了{1,#,3},所以需要加上后面的head + end)% 2,来防止这种事情的发生。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章