1. 程式人生 > >leetcode題目 合併N個排序好的連結串列

leetcode題目 合併N個排序好的連結串列

題目: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
思路: 兩種方法,第一種思路呼叫合併兩個排序好連結串列的函式,時間效率O(kN),k是連結串列個數,N是所有連結串列節點總數。第二種思路採用一個最小堆,先將k的連結串列的頭結點構造成一個最小堆,取出最小的元素,並將最小元素所在連結串列的下一個元素壓入堆中。直至堆為空。時間效率O(Nlogk)。本文兩種程式碼均實現了。
解法一: 容易理解,但是時間效率差。雖然在本地對資料量小的測試用例都通過了。但leetcode上本題的難度係數是困難,所以這種方法不會通過,結果是時間超限,

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(!lists.size())
            return NULL;

        ListNode* phead=NULL;
        for(auto i=lists.begin();i!=lists.end();++i)
        {
            phead=mergeTwoLists(phead,*i);
        }
        return
phead; } ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if(l1==NULL) return l2; if(l2==NULL) return l1; ListNode* pmerge=NULL; if(l1->val<l2->val) { pmerge=l1; pmerge->next=mergeTwoLists(l1->next,l2); } else
{ pmerge=l2; pmerge->next=mergeTwoLists(l1,l2->next); } return pmerge; } };

解法二: 利用堆,時間效率好,程式碼如下

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
       vector<ListNode*> heap;
       for(auto i=lists.begin();i!=lists.end();++i)
       {
           if(*i!=NULL)
                heap.push_back(*i);
       }

       //若堆為空,表示所有連結串列都為空或者lists本身為空
       if(!heap.size())  
           return NULL;

       ListNode* head,*p;
       make_heap(heap.begin(),heap.end(),greater);
       pop_heap(heap.begin(),heap.end(),greater);
       head=p=heap.back();
       heap.pop_back();

       //堆非空,取出最小結點,然後壓入最小結點的下一個結點
       while(heap.size())  
       {
           if(p->next!=NULL)
           {
               heap.push_back(p->next);
               push_heap(heap.begin(),heap.end(),greater);
           }
            pop_heap(heap.begin(),heap.end(),greater);
            p->next=heap.back();
            heap.pop_back();
            p=p->next;
       }
       return head;
    }

    //本程式堆中存放的是指標,並且要實現最小堆,所以寫一個簡單的比較函式
    static  bool greater(ListNode* l1,ListNode* l2)
    {
        if(l1->val>l2->val)
            return true;
        else
            return false;
    }
};

執行結果通過,並且擊敗了99.29%的程式碼有木有!!!
這裡寫圖片描述

相關推薦

leetcode題目 合併N排序連結串列

題目: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思路: 兩種方法,第一種思路呼叫合併兩個排序好連結串

LeetCode】21. Merge Two Sorted Lists 合併排序連結串列

Difficulty: Easy  More:【目錄】LeetCode Java實現 Description Merge two sorted linked lists and return it as a new list. The new list should be made by sp

劍指offer程式設計題python實現(第16題)合併排序連結串列

劍指offer程式設計題python實現(第16題)合併兩個排序的連結串列 題目描述 輸入兩個單調遞增的連結串列, 輸出兩個連結串列合成後的連結串列, 當然我們需要合成後的連結串列滿足單調不減規則。 '''題目描述 輸入兩個單調遞增的連結串列, 輸出兩個連結串列合成後的連結串列, 當然我們需

合併排序連結串列 java

合併兩個排序的連結串列 java 題目描述 輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。 程式碼1: public class Solution { public ListNode Merg

【劍指Offer】14合併排序連結串列

題目描述 輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。 時間限制:1秒;空間限制:32768K;本題知識點:連結串列 解題思路 # -*- coding:utf-8 -*- # class ListNode: #

劍指offer____合併排序連結串列

輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。   struct ListNode {     int val;     struct ListNode *next

[劍指offer] --17.合併排序連結串列

題目描述 輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。 /* public class ListNode { int val; ListNode next = null; ListNode(in

劍指offer_合併排序連結串列

題目描述 輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。 # -*- coding:utf-8 -*- # class ListNode: #     def __init__(self, x): #

劍指offer——(9)合併排序連結串列

/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solutio

[劍指offer] 16. 合併排序連結串列

題目描述 輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。 解法一: 非遞迴解 class Solution { public: ListNode *Merge(ListNode *pHe

劍指Offer16:合併排序連結串列

思路: 1.新建兩個連結串列mergeHead和p,初始值為90。 2.判斷pHead1.val和pHead2.val值的關係。 若pHead1.val>=pHead2.val,將pHead2放入mergeHead.next 然後pHead2指標往後移一步。 若pHead1.v

劍指offer:合併排序連結串列(java)

package linkedList; /** * 題目:(合併兩個排序的連結串列) * 輸入兩個遞增排序的連結串列,合併這兩個連結串列並使新連結串列 * 仍然是遞增排序的。 * 例如: * 連結串列1:1-3-5

劍指offer 25. 合併排序連結串列

1.問題描述 輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。 2.解決思路 1)非遞迴的方法 如果可以改變連結串列,直接從頭結點開始依次移動比較兩個連結串列當前值的大小,把較小的值作為當前結點的下一個結點。

劍指offer-16:合併排序連結串列

題目描述 輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。 程式碼 package jianzhioffer; /* public class ListNode { int val; ListNode n

劍指offer(16)合併排序連結串列

題目描述 輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。 解題思路 新建一個連結串列,儲存合併後的連結串列,返回 class Solution { public: ListNode* Merge(ListNode* p

牛客網線上程式設計專題《劍指offer-面試題17》合併排序連結串列

題目連結: 題目描述: 解題思路: (1)方法一: 修改兩個待合併連結串列的引用域,使它們稱為一個有序的連結串列list3。具體思路如下圖所示: 已經AC的程式碼: public class MergeLinkedList { // 定義結點

劍指offer--合併排序連結串列

題目描述 輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。 解析 將兩個連結串列排序插入vector陣列中,再新建一條連結串列。這種方法

重拾演算法之劍指Offier——合併排序連結串列

劍指Offier——合併兩個排序的連結串列 題目描述 輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。 /* public class ListNode { int val; ListNo

【劍指offer{15-18}】反轉連結串列合併排序連結串列、樹的子結構、二叉樹的映象

反轉連結串列、合併兩個排序的連結串列、樹的子結構、二叉樹的映象反轉連結串列題目描述C++程式碼題目描述C++程式碼樹的子結構題目描述C++程式碼題目描述C++程式碼 反轉連結串列 題目描述 輸入一

面試題25:合併排序連結串列

題目:輸入兩個遞增的排序連結串列,合併這兩個連結串列並使新連結串列中的節點仍然是遞增排序的。 c++實現: //合併兩個排序的連結串列 ListNode* merge(ListNode* pHead1, ListNode* pHead2) { if(