文章目录
- 题目描述
- 解法 & 代码
- 二刷
冲的第一道hard,好耶!
题目描述
- 这道题和前面的合并两个有序链表很有联系。直接调用了整个合并函数。
- 可以看成我们已经有了足够优秀的“两条链表合并“的函数,然后考虑对K条链表如何进行合并分配。
- 结构类似归并排序噢~
解法 & 代码
- 对K条链表,用一个merge不断二分;当merge只有两条时,进行twoList合并操作。只有一条时,直接返回当前链表。(这也解决了在二分时出现奇数的问题
- 之前考虑过不用merge,直接for循环一次合并入一条,也能过,但是复杂度会到O((m+n)*k)。
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode mergeKLists(ListNode[] lists) {// 数组空的情况,和数组为null的情况if(lists == null || lists.length == 0){return null;}return merge(lists, 0, lists.length - 1);}// 递归进行合并操作,复杂度log(n)public ListNode merge(ListNode[] lists, int left, int right){// 数组就一条链表的情况 && if (left == right)return lists[left];// 返回左、右两部分数组链表的两个结果,然后进行链表的两两合并twoList();return twoList(merge(lists,left, (right + left) / 2), merge(lists, (right + left) / 2 + 1, right));}// 放入两条链表,返回一条合并链表// 时间复杂度O(m+n)public ListNode twoList(ListNode l1, ListNode l2) {// 有链表为空的情况if(l1 == null)return l2;if(l2 == null)return l1;else if(l1.val < l2.val) {l1.next = twoList(l1.next,l2);return l1;}else {l2.next = twoList(l2.next,l1);return l2;}}
}
- 时间复杂度O((m+n)*log(k)),也就是两链表合并的复杂度乘上K链表合并的复杂度
- 空间复杂度O(1)
二刷
- 这道题怎么样都是爆杀…hard友好题!
class Solution {public ListNode mergeKLists(ListNode[] lists) {if(lists == null || lists.length == 0) return null;return merge(lists, 0, lists.length - 1);}ListNode merge(ListNode[] lists, int left, int right) {if(left == right) return lists[left];if(left + 1 == right) return mergeTwoLists(lists[left], lists[right]);int mid = (left + right) / 2;return mergeTwoLists(merge(lists, left, mid), merge(lists, mid + 1, right));}ListNode mergeTwoLists(ListNode head1, ListNode head2) {if(head1 == null) return head2;if(head2 == null) return head1;if(head1.val < head2.val) {head1.next = mergeTwoLists(head1.next, head2);return head1;} else {head2.next =mergeTwoLists(head1, head2.next);return head2;}}
}