现在的位置: 首页 > 综合 > 正文

Convert Sorted List to Binary Search Tree

2018年04月12日 ⁄ 综合 ⁄ 共 1363字 ⁄ 字号 评论关闭

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

这回给的是List了,所以我们无法在O(1)的时间得到中间的元素,然后二分。

当然如果能使用额外的空间的话,那我们很容易开辟一个数组然后复制List中的元素,得到以个排序数组,然后用上一题的方法来求解,这样的解法是时间O(n),空间O(n)。

第二种方法呢,我们每次从头遍历到中间那个元素(事先要先遍历求得当前链表的长度),然后分开分别求左子树和右子树,每次长度为k的时候要扫描 k/2个元素来找到中间那个,因为是二分,所以时间复杂度是O(n log n)的,空间呢,是O(1)的。

 

但是既然有了上一题,那这一题的初衷肯定不是用上两种朴素的方法来求解的,我试了一下都能AC,但是在面试时提出这样的解法肯定是不会满意的。

有没有其他方法呢?

我们这么想递归:首先我们知道这个链表有n个节点了,那么n/2的这个元素是我们要找的树根,那么前 n/2个元素自然就是它的左子树咯~

这句话好好理解一下。

这么想:如果我们能把当前给定的n个节点建立一棵树,然后把它添加到它的父亲的孩子指针上不就完了吗,有没有有点绕~既然我们的函数能将n长的链表建立一个子树并返回,那么我们可以先把前n/2个节点建立得到左子树,然后n/2这个节点是根,然后是右子树,这样就可以自底向上在遍历链表的同时建立排序树了。

讲还是貌似讲的有点绕啊~好好理解一下吧。

看代码吧~

/**
 * 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) {}
 * };
 */
class Solution {
public:
    TreeNode *sortedListToBST(ListNode *head) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
    	int n=getLen(head);
	return construct(head,n);
    }
    TreeNode* construct(ListNode*& head,int n)
    {
	    if(n==0)
		    return NULL;
	    int mid=n>>1;
	    TreeNode* left=construct(head,mid);
	    TreeNode* root=new TreeNode(head->val);
	    head=head->next;
	    root->left=left;
	    root->right=construct(head,n-mid-1);
	    return root;
    }
    int getLen(ListNode* head)
    {
	    int k=0;
	    while(head)
	    {
		    k++;
		    head=head->next;
	    }
	    return k;
    }
};


 

抱歉!评论已关闭.