题目描述
给你链表的头结点head,请将其按升序排列并返回排序后的链表。
解题思路
对于需要排序的题目,我认为通法都是小根堆,由于本题还涉及链表操作,使用尾插法将堆转换成链表即可,步骤如下:
- 将链表结点依次放进小根堆中
- 让两个结点都指向head,res用于返回最终结果,cur用于循环遍历
- 每次弹出一个堆顶元素,覆盖原链表的数据,以上图所示链表为例,尾插法的4次循环结果如下:
-初始res = cur = head = [4, 2, 1, 3]
-第1次循环,1弹出,用help接收,放到cur的next位置,由于cur指向head位置,故[2, 1, 3]被[1]覆盖,res = cur = [4, 1],cur指向next,为null
-第2次循环,2弹出,放到cur.next位置,即尾插入,链接[2],res = cur = [4, 1, 2]
-第3次循环,同尾插,res = cur = [4, 1, 2, 3]
-第4次循环,同尾插,res = cur = [4, 1, 2, 3, 4]
-堆空,跳出循环 - 这个方法是从head的第2个结点开始覆盖初始数据的,所以也要从第2个结点开始返回链表,即res.next = [1, 2, 3, 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; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
if(head == null) return head;
PriorityQueue<Integer> pq = new PriorityQueue<>();
ListNode node = head;
while(node != null) {
pq.offer(node.val);
node = node.next;
}
ListNode res = head;
ListNode cur = head;
while(pq.size() > 0) {
ListNode help = new ListNode(pq.poll());
cur.next = help;
cur = cur.next;
}
return res.next;
}
}