Merge k Sorted Lists

Merge k Sorted Lists

题目

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

分析

这道题目LeetCode给出的难度是hard。如果不考虑复杂度,个人感觉这道题的难度达不到hard
这道题相比之前Merge Two Sorted Lists,难度有所上升。这道题要合并的是k个有序链表。假设每个链表的长度都是m,那么合并两个链表的时间复杂度是O(m)

其中一种解法就是参照之前合并两个有序链表的做法,不断取出k个链表中的最小值,但是每次都得比较k个元素,时间复杂度较高。

另一种解法是合并前两个链表为一个链表,然后不断地将新链表和下一个链表合并得到新链表。即:

ListNode result = lists[0];
for (int i = 1; i < lists.length; i++) {
	result = mergeTwoLists(result, lists[i]);
}
return result;

但是该解法的时间复杂度也不是很理想。时间复杂度大概为 O ( k 2 ∗ m ) O(k^2*m) O(k2m)(合并最后两个链表的时间复杂度为 O ( k m ) O(km) O(km)而不是 O ( m ) O(m) O(m))。

二路归并解法:
该方法参照二路归并排序的思路。
将给出的k个链表每两个链表合并为一个新的链表。然后对新产生的所有链表重复该该合并操作直到剩下一个链表为止。剩下的那个链表就是最终的链表。
该方法的时间复杂度较为理想,大概是 O ( m ∗ k ∗ l o g k ) O(m*k*logk) O(mklogk)

代码如下

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
	private ListNode virtualNode = new ListNode(0);  // 虚拟节点
	public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) return null;
        ListNode result = null;
        int tempLength = lists.length;
        while (tempLength > 1) {
        	int j = tempLength / 2 + tempLength % 2;
        	for (int i = 0; i < tempLength / 2; i++) {
        		ListNode temp = mergeTwoLists(lists[i], lists[i + j]);
        		lists[i] = temp;
        	}
        	tempLength = j;
        }
        return lists[0];
    }
    // 合并两个有序链表的方法
    private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    	ListNode newList = virtualNode;
    	ListNode tempNode = newList;  // 临时节点
    	while (l1 != null && l2 != null) {
    		if (l1.val <= l2.val) {
    			tempNode = tempNode.next = l1;
    			l1 = l1.next;
    		} else {
				tempNode = tempNode.next = l2;
				l2 = l2.next;
			}
    	}
    	if (l1 == null) {
    		tempNode.next = l2;
    	} else {
			tempNode.next = l1;
		}
        return newList.next;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值