LeetCode Convert Sorted List to Binary Search Tree

109. Convert Sorted List to Binary Search Tree

Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

Example:

Given the sorted linked list: [-10,-3,0,5,9],

One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:

      0
     / \
   -3   9
   /   /
 -10  5

这一题和之前的LeetCode Convert Sorted Array to Binary Search Tree思路是一样的,只是把数组换成了链表,这样的话,就不能通过下标直接访问到中点元素了。 此时只能通过遍历找到链表的中点,然后以中点为根节点建树,最后分割左右链表,递归建树。完整代码如下:

class Solution {
public:
    TreeNode* sortedListToBST(ListNode* head)
    {
        if (head == NULL)
            return NULL;
        if (head->next == NULL)
            return new TreeNode(head->val);
        int n = 0, cnt = 0;
        ListNode* tmp = head;
        while (tmp != NULL) {
            n++;
            tmp = tmp->next;
        }
        tmp = head;
        while (cnt < n / 2 – 1) {
            tmp = tmp->next;
            cnt++;
        } // 此时tmp是中间节点的上一个节点
        TreeNode* root = new TreeNode(tmp->next->val);
        ListNode* head2 = tmp->next->next;
        tmp->next = NULL; // 断开
        root->left = sortedListToBST(head);
        root->right = sortedListToBST(head2);
        return root;
    }
};

本代码提交AC,用时22MS。击败了87%的人:-)
后来想想这题会不会有更优的解法,网上看了一下,发现自己蠢到哭了,链表找中点居然用了这么笨的方法,之前的快慢指针都忘了。换上快慢指针找链表中点的解法如下:

class Solution {
public:
    TreeNode* sortedListToBST(ListNode* head)
    {
        if (head == NULL)
            return NULL;
        if (head->next == NULL)
            return new TreeNode(head->val);
        ListNode *fast = head, *slow = head, *prior = head;
        while (fast->next != NULL && fast->next->next != NULL) {
            prior = slow;
            slow = slow->next;
            fast = fast->next->next;
        } // 此时slow为中间节点,prior为中间节点的上一个节点
        TreeNode* root = new TreeNode(slow->val);
        ListNode* head2 = slow->next;
        prior->next = NULL; //断开
        if (head != slow)
            root->left = sortedListToBST(head);
        root->right = sortedListToBST(head2);
        return root;
    }
};

本代码提交AC,用时26MS,有点失望,按理说这种解法是要比我上面的解法快的。
后来我又发现,这两种解法构建出来的平衡二叉搜索树不一样,如下图所示,但是他们都还算紧凑,都是正确的,看来答案不唯一啊。(其实主要是偶数长度时,有两个中间节点,选哪个都是正确的。)

Leave a Reply

Your email address will not be published. Required fields are marked *