leetcode第23题——***Merge k Sorted Lists

25 篇文章 0 订阅
25 篇文章 0 订阅

题目

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

思路

将数组中的k个有序链表归并成一个有序链表,并分析时间复杂度。该题可以在第22题-"merge two sorted lists"的基础上设计算法。
一开始想到遍历数组的k-1个链表,将第一个链表与第二个链表合并成一个新链表,然后第三个链表再跟这个新链表合并成新链表,以此类推......假设链表长度最长为n,则这样设计出来的算法时间复杂度为O(n*k),提交报超时错误。
改变思路,不要用单一遍历方式。可以递归归并数组中的k个链表,将其分割成k/2大小的数组归并,然后再分成k/2^2大小的数组归并......这样递归归并的时间复杂度为O(logk),总时间复杂度为O(n*logk)

代码

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

class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        if(len(lists) == 0):
            return
        return self.merge(lists,0,len(lists) - 1)
        
    def merge(self,lists,start,end):
        if(start == end):
            return lists[start]
            
        if(end - start == 1):
            return self.mergeTwoLists(lists[start],lists[end])
            
        mid = start + (end - start)/2
        return self.mergeTwoLists(self.merge(lists,start,mid),self.merge(lists,mid+1,end))
            
    def mergeTwoLists(self, l1, l2):  
        """ 
        :type l1: ListNode 
        :type l2: ListNode 
        :rtype: ListNode 
        """  
        head = ListNode(0)  
        cur = head  
          
        while(l1 != None and l2 != None):  
            #遍历l1和l2的节点并比较大小,将小的放入目标链表中,cur为游标  
            if(l1.val < l2.val):  
                cur.next = l1  
                l1 = l1.next  
            else:  
                cur.next = l2  
                l2 = l2.next  
            cur.next.next = None  
            cur = cur.next  
              
        #比较完l1和l2后还有剩余节点  
        if(l1 != None):  
            cur.next = l1  
        else:  
            cur.next = l2  
              
        return head.next
Java
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
		if (lists.length == 0)
			return null;
		return merge(lists, 0, lists.length - 1);//另外定义了一个根据数组下标merge的函数
	}

	public ListNode merge(ListNode[] lists, int start, int end) {
		if (start == end)
			return lists[start];
		if (end - start == 1)
			return mergeTwoLists(lists[start], lists[end]);

		int mid = start + (end - start) / 2;
		//递归merge,merge k/2个,k/2^2,k/2^3...直到merge两个或一个
		return mergeTwoLists(merge(lists, start, mid),merge(lists, mid + 1, end));
	}

	public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
		ListNode head = new ListNode(0);
		ListNode cur = head;
		// 遍历l1和l2的节点并比较大小,cur代表当前节点
		while (l1 != null && l2 != null) {
			if (l1.val < l2.val) {
				cur.next = l1;
				l1 = l1.next;
			} else {
				cur.next = l2;
				l2 = l2.next;
			}
			cur.next.next = null;// 可减少链表大小,提高效率
			cur = cur.next;
		}

		// 比较完l1和l2的节点后还有剩余节点
		if (l1 != null)
			cur.next = l1;
		else
			cur.next = l2;

		return head.next;
	}
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值