題幹
convert-sorted-link-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,來防止這種事情的發生。