QUESTION
medium
题目描述
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树
本题中,一个高度平衡二叉树是指一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1
示例:
给定的有序链表:[-10, -3, 0, 5, 9]
一个可能的答案是:[0, -3, 9, -10, null, 5]
, 它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
说明
无
SOLUTION
熟知 BST
的一个性质:中序遍历严格递增
明白了这个,那么这道题就很简单了,整个递增的有序链表,每次都找到中间节点的作为一个子树的根,就能保证平衡
方法一
要在链表上访问实在太麻烦了,直接把链表的全部值放进一个数组里,再进行操作就很方便
class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
if(!head) return NULL;
vector<int> list;
ListNode* p = head;
while(p){
list.push_back(p->val);
p = p->next;
}
return build(list, 0 ,list.size() - 1);
}
TreeNode* build(vector<int> &list, int l, int r){
if(l > r) return NULL;
int mid = (r + l) / 2;
TreeNode* t = new TreeNode(list[mid]);
t->left = build(list, l, mid - 1);
t->right = build(list, mid + 1, r);
return t;
}
};
方法二
方法一使用数组完成,感觉有些投机取巧,那么有没有直接在链表上操作的方法呢?当然有,如果你之前有做过关于链表的题目那你一定能很快反应过来—— 快慢指针
- 要找到中点,快指针走两步,慢指针走一步即可
class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
return build(head, NULL);
}
TreeNode* build(ListNode* front, ListNode* back){
if(front == back) return NULL;
ListNode *slow = front, *fast = front;
while(fast->next != back && fast->next->next != back){
slow = slow->next;
fast = fast->next->next;
}
TreeNode *t = new TreeNode(slow->val);
t->left = build(front, slow);
t->right = build(slow->next, back);
return t;
}
};