简体   繁体   中英

LeetCode: Problem 23 - Merge K Sorted Lists

The problem stated on LeetCode is as follows:

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

Example:

Input: [ 1->4->5, 1->3->4, 2->6 ] Output: 1->1->2->3->4->4->5->6

I am able to pass 129 out of 131 test cases but hit "time limit exceeded" on case 130. Below is my implementation.

Can someone spot the bottleneck? Any suggestions on improving time complexity?

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

class Solution:
    # def print_lists(self, lists):
    #     idx = 0
    #     while idx < len(lists):
    #         ptr = lists[idx]
    #         _l = []
    #         while ptr is not None:
    #             _l.append(ptr.val)
    #             ptr = ptr.next
    #         idx += 1
    #         print(_l)

    def min_idx(self, lists):
        idx = 0

        for i in range(len(lists)):
            if lists[i] is None:
                continue
            elif lists[idx] is None:
                idx = i
            elif lists[i].val < lists[idx].val:
                idx = i
        return idx

    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        head = tail = ListNode(-1)

        while len(lists) > 0:
            m_idx = self.min_idx(lists)

            if lists[m_idx] is None:
                return head.next

            tail.next = lists[m_idx]
            tail = tail.next
            lists[m_idx] = lists[m_idx].next

            if lists[m_idx] is None:
                del lists[m_idx]

        return head.next

I run into the "time limit exceeded" issue with our without using del . Test case 130 contains 10,000 LinkedLists.

Here is a simpler and faster version of your code that avoids several ifs:

def min_idx(self, lists):
    idx = 0

    for i in range(len(lists)):
        if lists[i].val < lists[idx].val:
            idx = i
    return idx

def mergeKLists(self, lists):
    head = tail = ListNode(-1)

    lists = list(filter(lambda x: x is not None, lists))

    while len(lists) > 0:
        m_idx = self.min_idx(lists)

        tail.next = lists[m_idx]
        tail = tail.next
        lists[m_idx] = lists[m_idx].next

        if lists[m_idx] is None:
            del lists[m_idx]

    return head.next

For an even better time you will need to change the implementation to either:

  • Use heap to reduce the min_idx operation to O(log k) instead of O(k) being k the amount of lists
  • Just throw all to a single array, sort it and put it back into a ListNode
  • Make the merging of 2 lists in O(length of longest list) and recursively merge in pairs until 1 left

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM