【Lintcode】104. Merge K Sorted Lists

题目地址:

https://www.lintcode.com/problem/merge-k-sorted-lists/description

给定一个list,里面的元素都是链表的头结点。每个链表都是单调增的。要求返回一个链表,其为这些链表的单调增的合并。

法1:用堆。开一个最小堆,然后将所有非null的头结点加进最小堆,接着每次都从堆顶取出一个链表节点,加到最终要返回的链表的尾部,然后将那个链表节点的next节点(非null的)加进最小堆,直到所有链表都遍历完为止。代码如下:

import java.util.List;
import java.util.PriorityQueue;

public class Solution {
    /**
     * @param lists: a list of ListNode
     * @return: The head of one sorted list.
     */
    public ListNode mergeKLists(List<ListNode> lists) {
        // write your code here
        ListNode dummy = new ListNode(0), cur = dummy;
        PriorityQueue<ListNode> minHeap = new PriorityQueue<>((n1, n2) -> n1.val <= n2.val ? -1 : 1);
        // 将所有非null的链表头结点加入最小堆中
        for (ListNode head : lists) {
            if (head != null) {
                minHeap.offer(head);
            }
        }
        
        while (!minHeap.isEmpty()) {
        	// 从堆顶取出节点,加到cur后面,同时cur后移一步
        	// 接着将取出的节点的非null的next节点加进最小堆
            ListNode min = minHeap.poll();
            cur.next = min;
            cur = cur.next;
            // 要判断非null
            if (min.next != null) {
                minHeap.offer(min.next);
            }
        }
        
        return dummy.next;
    }
}

class ListNode {
    int val;
    ListNode next;
    ListNode(int val) {
        this.val = val;
    }
}

时间复杂度 O ( n log ⁡ k ) O(n\log k) O(nlogk) n n n为链表总长度, k k k为链表的个数。空间复杂度 O ( k ) O(k) O(k)

法2:分治法。如果lists长度为 1 1 1,那么直接返回这个链表就行了。否则的话,我们可以递归合并lists的左半部分链表和右半部分链表,最后再将两部分合并出来的两个链表最后做个合并即可。代码如下:

import java.util.List;

public class Solution {
    /**
     * @param lists: a list of ListNode
     * @return: The head of one sorted list.
     */
    public ListNode mergeKLists(List<ListNode> lists) {
        // write your code here
        return merge(lists, 0, lists.size() - 1);
    }
    
    // 作用是将lists从l到r部分的链表合并并返回
    private ListNode merge(List<ListNode> lists, int l, int r) {
    	// 如果[l, r]里只有一个链表,则直接返回即可
        if (l == r) {
            return lists.get(l);
        }
        
        int m = l + (r - l >> 1);
        // 递归合并左右两半部分
        ListNode l1 = merge(lists, l, m);
        ListNode l2 = merge(lists, m + 1, r);
        // 开始合并l1和l2
        ListNode dummy = new ListNode(0), cur = dummy;
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                cur.next = l1;
                l1 = l1.next;
            } else {
                cur.next = l2;
                l2 = l2.next;
            }
            cur = cur.next;
        }
        
        cur.next = l1 != null ? l1 : l2;
		return dummy.next;
    }
}

时间复杂度 O ( n log ⁡ k ) O(n\log k) O(nlogk),空间复杂度 O ( log ⁡ k ) O(\log k) O(logk),递归栈深度。

时间复杂度证明:
设时间消耗为 T ( k , n ) T(k, n) T(k,n),那么: T ( k , n ) = T ( k 2 , n 1 ) + T ( k 2 , n 2 ) + O ( n ) = . . . = O ( n log ⁡ k ) T(k,n)=T(\frac{k}{2},n_1)+T(\frac{k}{2},n_2)+O(n)=...=O(n\log k) T(k,n)=T(2k,n1)+T(2k,n2)+O(n)=...=O(nlogk)得证。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
To merge k sorted linked lists, one approach is to repeatedly merge two of the linked lists until all k lists have been merged into one. We can use a priority queue to keep track of the minimum element across all k linked lists at any given time. Here's the code to implement this idea: ``` struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(NULL) {} }; // Custom comparator for the priority queue struct CompareNode { bool operator()(const ListNode* node1, const ListNode* node2) const { return node1->val > node2->val; } }; ListNode* mergeKLists(vector<ListNode*>& lists) { priority_queue<ListNode*, vector<ListNode*>, CompareNode> pq; for (ListNode* list : lists) { if (list) { pq.push(list); } } ListNode* dummy = new ListNode(-1); ListNode* curr = dummy; while (!pq.empty()) { ListNode* node = pq.top(); pq.pop(); curr->next = node; curr = curr->next; if (node->next) { pq.push(node->next); } } return dummy->next; } ``` We start by initializing a priority queue with all the head nodes of the k linked lists. We use a custom comparator that compares the values of two nodes and returns true if the first node's value is less than the second node's value. We then create a dummy node to serve as the head of the merged linked list, and a current node to keep track of the last node in the merged linked list. We repeatedly pop the minimum node from the priority queue and append it to the merged linked list. If the popped node has a next node, we push it onto the priority queue. Once the priority queue is empty, we return the head of the merged linked list. Note that this implementation has a time complexity of O(n log k), where n is the total number of nodes across all k linked lists, and a space complexity of O(k).

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值