LeetCode 题解(79): Merge k Sorted Lists

题目:

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

题解:

采用Heap的方法,C++和Java用Priority Queue + customized comparator实现最小堆,Python直接使用heapq, heapq.heappush, heapq.heappop。算法复杂度,每加入一个元素进堆,需要O(lgk)时间,k为lists中list的个数。共有nk个元素,所以总共需要O(nklgk)时间加入全部元素,其中n为每个list的元素个数的最大值。每次取最小值为O(1)时间复杂度,所以总共为O(nklgk)时间复杂度。

c++版:

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

struct comparator {
    bool operator() (ListNode* i, ListNode* j) {
        return i->val > j->val;
    }
};

class Solution {
public:
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        if(!lists.size())
            return NULL;
        ListNode* dummyHead = new ListNode(0);
        ListNode* pointer = dummyHead;
        priority_queue<ListNode*, vector<ListNode*>, comparator> heap;
        for(int i = 0; i < lists.size(); i++) {
            heap.push(lists[i]);
        }
        while(heap.size()) {
            ListNode* temp = heap.top();
            heap.pop();
            pointer->next = temp;
            pointer = pointer->next;
            
            if(temp->next)
                heap.push(temp->next);
        }
        return dummyHead->next;
        
    }
};

int main(int argc, char** argv) {
    
    ListNode* h1 = new ListNode(3);
    ListNode* h2 = new ListNode(2);
    ListNode* h3 = new ListNode(1);
    ListNode* n12 = new ListNode(5);
    ListNode* n13 = new ListNode(7);
    ListNode* n14 = new ListNode(9);
    ListNode* n22 = new ListNode(4);
    ListNode* n23 = new ListNode(6);
    ListNode* n24 = new ListNode(8);
    ListNode* n32 = new ListNode(3);
    ListNode* n33 = new ListNode(4);
    ListNode* n34 = new ListNode(8);
    
    h1->next = n12;
    n12->next = n13;
    n13->next = n14;
    
    h2->next = n22;
    n22->next = n23;
    n23->next = n24;
    
    h3->next = n32;
    n32->next = n33;
    n33->next = n34;
    
    vector<ListNode*> input;
    input.push_back(h1);
    input.push_back(h2);
    input.push_back(h3);
    
    Solution s;
    ListNode* result = s.mergeKLists(input);
    while(result) {
        cout << result->val << " ";
        result = result->next;
    }
    cout << endl;
    
    return 0;
}


Java版:

package leetcode;

import java.util.*;

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
        next = null;
    }
}

class MyComparator implements Comparator<ListNode>{
    public int compare(ListNode x, ListNode y) {
        return x.val - y.val;
    }
}

class Solution {
    public ListNode mergeKLists(List<ListNode> lists) {
        if(lists.size() == 0)
            return null;
        ListNode dummyHead = new ListNode(0);
        PriorityQueue<ListNode> minHeap = new PriorityQueue<ListNode>(lists.size(), new MyComparator());
        ListNode pointer = dummyHead;
        for(int i = 0; i < lists.size(); i++) {
            if(lists.get(i) != null)
                minHeap.add(lists.get(i));
        }
        while(minHeap.size() != 0) {
            ListNode temp = minHeap.poll();
            pointer.next = temp;
            
            if(temp.next != null)
                minHeap.add(temp.next);
            pointer = pointer.next;
        }
        return dummyHead.next;
    }
}

public class Leetcode {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        ListNode h1 = new ListNode(1);
        ListNode h2 = new ListNode(2);
        ListNode h3 = new ListNode(1);
        ListNode n12 = new ListNode(5);
        ListNode n13 = new ListNode(7);
        ListNode n14 = new ListNode(9);
        ListNode n22 = new ListNode(4);
        ListNode n23 = new ListNode(6);
        ListNode n24 = new ListNode(8);
        ListNode n32 = new ListNode(3);
        ListNode n33 = new ListNode(4);
        ListNode n34 = new ListNode(8);
        
        h1.next = n12;
        n12.next = n13;
        n13.next = n14;
    
        h2.next = n22;
        n22.next = n23;
        n23.next = n24;
    
        h3.next = n32;
        n32.next = n33;
        n33.next = n34;
    
        List<ListNode> input = new ArrayList<ListNode>();
        input.add(h1);
        input.add(h2);
        input.add(h3);
    
        Solution s = new Solution();
        ListNode result = s.mergeKLists(input);
        while(result != null) {
            System.out.print(result.val);
            System.out.print(" ");
            result = result.next;
        }
        System.out.println();
    }
    
}

Python版:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    # @param a list of ListNode
    # @return a ListNode
    def mergeKLists(self, lists):
        if len(lists) == 0:
            return None
        h = []
        dummyHead = ListNode(0)
        pointer = dummyHead
        for i in range(0,len(lists)):
            if lists[i] != None:
                heapq.heappush(h, (lists[i].val, lists[i]))
        while len(h) != 0:
            temp = heapq.heappop(h)
            pointer.next = temp[1]
            if temp[1].next != None:
                heapq.heappush(h, (temp[1].next.val, temp[1].next))
            pointer = pointer.next
        return dummyHead.next
            


你可能感兴趣的:(Algorithm,LeetCode,面试题)