LeetCode - 23. Merge k Sorted Lists

23. Merge k Sorted Lists

Brute Force

所有node sort一遍
time complexity - O(NlogN) [N = the total number of nodes in all linked lists]
space complexity - O(N)

Divide and Conquer | MergeSort

Use merge two,两两合并最后成一个
不同方法写merge2, check out: LeetCode - 21. Merge Two Sorted Lists_real_lisa的博客-CSDN博客

def mergeTwoLists(self, list1: ListNode, list2: ListNode) -> ListNode:
        res = head = ListNode(0);
        while(list1 and list2):
            if list1.val < list2.val:
                res.next = list1
                list1 = list1.next
            else:
                res.next = list2
                list2 = list2.next
            res = res.next
        res.next = list1 or list2
        return head.next

Most optimized for merge two:
time complexity - O(2n) [n = average num of nodes in each Linked List]
space complexity - O(1) in-place

Recursion

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

class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        if not lists: return None
        length = len(lists)
        if length == 1: return lists[0]
        mid = int(length/2)
        return self.mergeTwoLists(self.mergeKLists(lists[:mid]), self.mergeKLists(lists[mid:]))

Iteration 1

class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        amount = len(lists)
        interval = 1
        while interval < amount:
            for i in range(0, amount - interval, interval * 2):
                lists[i] = self.merge2Lists(lists[i], lists[i + interval])
            interval *= 2
        return lists[0] if amount > 0 else lists

Iteration 2

def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        if not lists: return None
        length = len(lists)
        while(length != 1):
            newLists = []
            if len(lists)%2 == 1: newLists.append(lists[-1])
            for i in range(1, length, 2):
                newLists.append(self.mergeTwoLists(lists[i-1], lists[i]))
            lists = newLists
            length = len(lists)
        return lists[0]

Iteration 3

class Solution {
public:
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        if(lists.empty()) return NULL;
        int end = lists.size()-1;
        while(end>0) {
            int begin = 0;
            while(begin<end) {
                lists[begin] = merge2Lists(lists[begin], lists[end]);
                begin++;
                end--;
            }
        }
        return lists[0];
    }

Time Complexity

k = num of Linked List
n = average num of nodes in each Linked List
2n*k/2 + 4n*k/4 + ... + (2^x)*n*k/(2^x)
= n*k + n*k + ... + n*k (有x个这样的n*k)
= n*k*x
explain 2n*k/2:
第一次运行:每两个Linked List的num of nodes=2n, 运行merge2合并为O(2n);有k/2对这样的Linked List,所以第一次两两合并的time complexity是2n*k/2
(2^x)*n*k/(2^x)为最后一次运行,k/(2^x)为最后剩余Linked List的个数,所以k/(2^x)=1, 得x=logk
n*k*x = n*k*(logk)
所以最后的time complexity为
O(nklogk) = O(Nlogk) [N = nk = the total number of nodes in all linked lists]

Heap

每次选择k lists中最小的

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        heap = [(node.val, i, node) for i,node in enumerate(lists) if node]
        heapq.heapify(heap)
        cur = dummy = ListNode(0)
        while heap:
            val, i, node = heapq.heappop(heap)
            cur.next = ListNode(val)
            cur = cur.next
            if node.next:
                heapq.heappush(heap, (node.next.val, i, node.next))
        return dummy.next

Time Complexity

k = num of Linked List
N = the total number of nodes in all linked lists
每次选择k lists中最小的 - O(logk),选择N次 ----> O(Nlogk)
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值