Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
题目解析:
方案一:
将一个链表构建成一颗平衡二叉树,也可以借鉴上一题的方法,找到中间节点为根,然后左右递归。但是过程中出现了错误:
Submission Result: Runtime Error
Last executed input: {-1,0,1,2}
是不是我选的是0为根,而系统选的是1为根……现在还不知道,回头再考察一下,要修改……
class Solution {
public:
TreeNode *sortedListToBST(ListNode *head) {
if(head == NULL)
return NULL;
int n = 1;
ListNode *p = head;
while(p->next){
n++;
p = p->next;
}
return GenerateSubTree(head,n);
}
TreeNode *GenerateSubTree(ListNode *head,int n){
if(n==0)
return NULL;
if(n==1){
TreeNode *T = new TreeNode(head->val);
T->left = NULL;
T->right = NULL;
return T;
}
int count = 1;
int mid = n/2; //找到中间节点当父节点,然后递归
ListNode *p = head;
while(count<mid)
p = p->next;
TreeNode *T = new TreeNode(p->val);
T->left = GenerateSubTree(head,mid-1);
T->right = GenerateSubTree(p->next,n-n/2);
return T;
}
};
方案二:
很巧妙的方法,类似于中序遍历,先产生左子树,然后产生根,最后产生右子树。
二分法和中序遍历二叉树的高级结合应用。综合难度指数五星级。
难点:
1 如何设计二分法的结束条件?
2 如何中序先构造左子树,然后构造根节点,然后是右子树?
3 如何确定根节点?
4 如何返回节点,如何确定返回的节点是左子树还是右子树?
5 什么时候递归?
好多问题的一个算法设计,但是只要理解透切了,一切问题都可以归结为几行简单的代码
TreeNode *sortedListToBST(ListNode *head)
{
int n = getLength(head);
return toBST(head, 0, n-1);
}
int getLength(ListNode *h)
{
int n = 0;
for ( ; h; n++) h = h->next;
return n;
}
TreeNode *toBST(ListNode *&h, int low, int up)
{
if (low > up) return nullptr;
int m = low + ((up-low)>>1);
TreeNode *lt = toBST(h, low, m-1);
TreeNode *r = new TreeNode(h->val);
h = h->next;
r->left = lt;
r->right = toBST(h, m+1, up);
return r;
}