您的位置:首页 > 编程语言 > Python开发

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

2016-03-01 23:11 851 查看

题目

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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java leetcode python