leetcode第23题——***Merge k Sorted Lists
2016-03-01 23:11
851 查看
题目
Merge k sortedlinked 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对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 介绍一款信息管理系统的开源框架---jeecg
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- install and upgrade scrapy
- Scrapy的架构介绍