【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,來防止這種事情的發生。

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