题目链接:https://leetcode.cn/problems/sort-list/?envType=study-plan-v2&envId=top-100-liked
第一种,插入排序,会超时
class Solution {
public ListNode sortList(ListNode head) {
//插入排序,用较为简单的方式解决
ListNode dummyNode = new ListNode(0,null);
ListNode p = head;
while(p!=null){
ListNode temp = p;
p=p.next;
//将temp插入到链表当中
ListNode q = dummyNode;
int flag = 0;
while(q.next!=null){
if(q.next.val>=temp.val){
ListNode t = q.next;
q.next = temp;
temp.next = t;
flag= 1;
break;
}
q = q.next;
}
//说明插在最后一个
if(flag==0){
q.next = temp;
temp.next = null;
}
}
return dummyNode.next;
}
}
第二种,推荐面试直接写,堆排序,借助优先队列,能5分钟秒了
/**
* 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 sortList(ListNode head) {
//推荐使用优先队列
PriorityQueue<ListNode> queue = new PriorityQueue<>(new Comparator<>(){
public int compare(ListNode a ,ListNode b){
return a.val-b.val;
}
});
ListNode p = head;
while(p!=null){
queue.offer(p);
p=p.next;
}
ListNode dummy = new ListNode(0);
ListNode q = dummy;
while(queue.isEmpty()==false){
ListNode node = queue.poll();
q.next = node;
q = q.next;
q.next = null;
}
return dummy.next;
}
}
第三种,归并排序,主要就是分为归并和合并两部分。合并很简单。拆分时候,通过快慢指针拆出来两个链表头。
class Solution {
public ListNode sortList(ListNode head) {
if(head==null||head.next==null)return head;
ListNode slow = head;
//这里一定一定要slow和fast分开
//不然 4 2 会出现,head一直是4,newHead一直是空的情况
ListNode fast = head.next;
while(fast!=null&&fast.next!=null){
fast = fast.next.next;
slow = slow.next;
}
ListNode newHead = slow.next;
slow.next = null;
return merge(sortList(head),sortList(newHead));
}
public ListNode merge(ListNode l1,ListNode l2){
ListNode p = l1;
ListNode q = l2;
ListNode dummy = new ListNode(0);
ListNode t = dummy;
while(p!=null&&q!=null){
if(p.val<q.val){
t.next = p;
p=p.next;
}else{
t.next = q;
q=q.next;
}
t=t.next;
}
t.next = p==null?q:p;
return dummy.next;
}
}