给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定的有序链表: [-10, -3, 0, 5, 9], 一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树: 0 / \ -3 9 / / -10 5
这道题关键是给定了有序的序列,所以我们只需要每次找出链表的中点作为树的根节点,然后递归调用原函数即可。其中,中点的寻找方法是快慢指针。我们需要注意边界的处理,这是递归容易忽略的问题:
其一:当head==nullptr时返回nullptr(叶子结点的子节点),当head->next==nullptr时返回new TreeNode(head->val)(叶子结点)
其二:由于我们使用了递归,一定要考虑全各种情况,当递归调用最后链表中还剩下0,1,2,3个节点时,会发生什么,当还剩0和1个节点时,上述情况已讨论过。当还剩2个节点时(比如a->b时),经过程序执行,last,slow指向a,fast指向b,这时slow会被作为中点,last会被作为除去a以前链表的尾节点,但是a已经被占用了,所以我们递归调用时一定要有这句条件判断:
if (slow != head) { cur->left = sortedListToBST(head); }
因为fast总是正确的,不需要判断。
以下是程序代码:
TreeNode* sortedListToBST(ListNode* head) { if (!head) { return nullptr; } if (!head->next) { return new TreeNode(head->val); } ListNode* fast; ListNode* slow; ListNode* last; fast = slow = last = head; while (fast->next && fast->next->next) { last = slow; slow = slow->next; fast = fast->next->next; } fast = slow->next; last->next = nullptr; TreeNode* cur = new TreeNode(slow->val); if (slow != head) { cur->left = sortedListToBST(head); } cur->right = sortedListToBST(fast); return cur; }