leetcode刷题笔记【13-14】
类型:链表的归并排序
148. 排序链表【中等】
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
示例 1:
输入:head = [4,2,1,3]
输出:[1,2,3,4]
示例 2:
输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]
示例 3:
输入:head = []
输出:[]
提示:
链表中节点的数目在范围 [0, 5 * 104] 内
-105 <= Node.val <= 105
进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
/**
* 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; }
* }
*/
//归并排序
//时间复杂度o(nlogn)
//空间复杂度o(1)
class Solution {
public ListNode sortList(ListNode head) {
return mergeList( head, null);
}
//左闭右开
ListNode mergeList(ListNode head,ListNode tail){
if(head==null){
return null;
}
if(head.next==tail){
head.next=null;
return head;
}
ListNode p=head,q=head;
while(q!=tail){
q=q.next;
if(q!=tail){
q=q.next;
}
p=p.next;
}
ListNode headA=mergeList(head,p);
ListNode headB= mergeList(p,tail);
p=headA;
q=headB;
ListNode dummy = new ListNode(),x=dummy;
while(p!=null&&q!=null){
if(p.val<q.val){
x.next=p;
p=p.next;
}else{
x.next=q;
q=q.next;
}
x=x.next;
}
if(p!=null){
x.next=p;
}else{
x.next=q;
}
return dummy.next;
}
}
- 合并 K 个升序链表【困难】
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:
输入:lists = []
输出:[]
示例 3:
输入:lists = [[]]
输出:[]
提示:
k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i] 按 升序 排列
lists[i].length 的总和不超过 10^4
/**
* 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; }
* }
*/
//顺序合并
//时间复杂度o(n*k^2)
//空间复杂度o(1)
// class Solution {
// public ListNode mergeKLists(ListNode[] lists) {
// int k = lists.length;
// ListNode ans=null;
// for(int i=0;i<k;i++){
// ans=mergeTwoLists(ans,lists[i]);
// }
// return ans;
// }
// public ListNode mergeTwoLists(ListNode a,ListNode b){
// if (a == null || b == null) {
// return a != null ? a : b;
// }
// ListNode head = new ListNode(0);
// ListNode p = head;
// while (a != null && b != null) {
// if (a.val < b.val) {
// p.next = a;
// a = a.next;
// } else {
// p.next = b;
// b = b.next;
// }
// p = p.next;
// }
// p.next = (a != null ? a : b);
// return head.next;
// }
// }
//优先队列
//时间复杂度o(kn*logk)
//空间复杂度o(k)
// class Solution {
// class Status implements Comparable<Status>{
// int val;
// ListNode ptr;
// Status(int val,ListNode ptr){
// this.val=val;
// this.ptr=ptr;
// }
// public int compareTo(Status status){
// return this.val-status.val;
// }
// }
// public ListNode mergeKLists(ListNode[] lists) {
// int k = lists.length;
// PriorityQueue<Status> pq = new PriorityQueue<>();
// for(int i=0;i<k;i++){
// if(lists[i]!=null)
// pq.add(new Status(lists[i].val,lists[i]));
// }
// ListNode dummy = new ListNode(0);
// ListNode p=dummy;
// while(!pq.isEmpty()){
// Status s = pq.poll();
// p.next=s.ptr;
// p=p.next;
// if(s.ptr.next!=null){
// pq.add(new Status(s.ptr.next.val,s.ptr.next));
// }
// }
// return dummy.next;
// }
// }
//手写小根堆
// class Solution {
// void buildHeap(ListNode[] lists,int size){
// for(int i=size/2;i>=0;i--){
// heapify(lists,i,size);
// }
// }
// void heapify(ListNode[] lists,int i,int size){
// int left=i*2+1,right=i*2+2,largest=i;
// if(left<size&&lists[largest].val>lists[left].val){
// largest=left;
// }
// if(right<size&&lists[largest].val>lists[right].val){
// largest=right;
// }
// if(i!=largest){
// swap(lists,i,largest);
// heapify(lists,largest,size);
// }
// }
// void swap(ListNode[] lists,int a,int b){
// ListNode tmp=lists[a];
// lists[a]=lists[b];
// lists[b]=tmp;
// }
// public ListNode mergeKLists(ListNode[] lists) {
// int k = lists.length,size=0;
// ListNode[] a=new ListNode[k];
// int j=0;
// for(int i=0;i<k;i++){
// if(lists[i]!=null){
// a[j++]=lists[i];
// }
// }
// size=j;
// buildHeap(a,size);
// ListNode dummy = new ListNode(0);
// ListNode p=dummy;
// while(size>0){
// ListNode node = a[0];
// p.next=node;
// p=p.next;
// if(node.next!=null){
// a[0]=node.next;
// heapify(a,0,size);
// }else{
// swap(a,0,size-1);
// size--;
// heapify(a,0,size);
// }
// }
// return dummy.next;
// }
// }
//分治合并
//时间复杂度o(nlogk)
//空间复杂度o(logk)
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
return merge(lists,0,lists.length-1);
}
ListNode merge(ListNode[] lists,int l,int r){
if(l>r) return null;
if(l==r) return lists[l];
int m=l+r>>1;
ListNode p=merge(lists,l,m);
ListNode q=merge(lists,m+1,r);
ListNode dummy = new ListNode(),k=dummy;
while(p!=null&&q!=null){
if(p.val<=q.val){
k.next=p;
p=p.next;
}else{
k.next=q;
q=q.next;
}
k=k.next;
}
if(p!=null) k.next=p;
else k.next=q;
return dummy.next;
}
}