[LeetCode] 从排序的单链表到平衡搜索二叉树

相关问题:给定一个数组,写个程序构造一个最矮的二叉树


给你一个排过序的单链表,构建一个平衡的搜索二叉树。

In this method, we construct from leaves to root. The idea is to insert nodes in BST in the same order as the appear in Linked List, so that the tree can be constructed in O(n) time complexity. We first count the number of nodes in the given Linked List. Let the count be n. After counting nodes, we take left n/2 nodes and recursively construct the left subtree. After left subtree is constructed, we allocate memory for root and link the left subtree with root. Finally, we recursively construct the right subtree and link it with root.
While constructing the BST, we also keep moving the list head pointer to next so that we have the appropriate pointer in each recursive call.

代码如下:

/* This function counts the number of nodes in Linked List and then calls
   sortedListToBSTRecur() to construct BST */
TNode* sortedListToBST(LNode *head)
{
    /*Count the number of nodes in Linked List */
    int n = countLNodes(head);
 
    /* Construct BST */
    return sortedListToBSTRecur(&head, n);
}
 
/* The main function that constructs balanced BST and returns root of it.
       head_ref -->  Pointer to pointer to head node of linked list
       n  --> No. of nodes in Linked List */
TNode* sortedListToBSTRecur(LNode **head_ref, int n)
{
    /* Base Case */
    if (n <= 0)
        return NULL;
 
    /* Recursively construct the left subtree */
    TNode *left = sortedListToBSTRecur(head_ref, n/2);
 
    /* Allocate memory for root, and link the above constructed left 
       subtree with root */
    TNode *root = new TNode((*head_ref)->data);
    root->left = left;
 
    /* Change head pointer of Linked List for parent recursive calls */
    *head_ref = (*head_ref)->next;
 
    /* Recursively construct the right subtree and link it with root 
      The number of nodes in right subtree  is total nodes - nodes in 
      left subtree - 1 (for root) which is n-n/2-1*/
    root->right = sortedListToBSTRecur(head_ref, n-n/2-1);
 
    return root;
}

/* A utility function that returns count of nodes in a given Linked List */
int countLNodes(struct LNode *head)
{
    int count = 0;
    struct LNode *temp = head;
    while(temp)
    {
        temp = temp->next;
        count++;
    }
    return count;
}

算法二:用slow和fast 两个指针寻找中间节点。注意如何对slow、fast进行初始化,如何更新slow和fast。这是我自己写的代码。

    TreeNode *sortedListToBST(ListNode *head) {
        if(head==NULL)
            return NULL;
        if(head->next==NULL)
        {
            TreeNode* root = new TreeNode(head->val);
            return root;
        }
        
        ListNode* prev_of_slow=NULL;
        ListNode* slow = head;
        ListNode* fast = head->next; // initialize fast to be the next of slow.
        
        // slow and fast pointers.
        while(1)
        {
            if(fast) // think about what is the difference betweem if(fast) and if(fast->next)
                fast = fast->next;
            else
                break;
                
            if(fast) // think about what is the difference betweem if(fast) and if(fast->next)
                fast = fast->next;
            else
                break;
                
            // By using 'if(fast)', the slow pointer will be the middle pointer in case of odd number of nodes
            // If using 'if(fast->next)', the slow pointer will not be the middle pointer in case of odd number of nodes
                
            prev_of_slow = slow;
            slow = slow->next;
        }
        
        TreeNode* root = new TreeNode(slow->val);
        
        if(prev_of_slow!=NULL)
        {
            prev_of_slow->next = NULL;
            TreeNode* leftRoot = sortedListToBST(head);       
            root->left = leftRoot;
        }
        
        TreeNode* rightRoot = sortedListToBST(slow->next);
        root->right = rightRoot;
        
        return root;
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值