题目描述
给你链表的头结点 head
,请将其按 升序 排列并返回 排序后的链表 。
示例 1:
1 2
| 输入:head = [4,2,1,3] 输出:[1,2,3,4]
|
示例 2:
1 2
| 输入:head = [-1,5,3,4,0] 输出:[-1,0,3,4,5]
|
示例 3:
提示:
- 链表中节点的数目在范围
[0, 5 * 10^4]
内
-10^5 <= Node.val <= 10^5
进阶:你可以在 O(n log n)
时间复杂度和常数级空间复杂度下,对链表进行排序吗?
解法
- 归并排序
- 找到链表的中点,以中点为分界,将链表拆分成两个子链表。
- 寻找链表的中点可以使用快慢指针的做法,快指针每次移动 2 步,慢指针每次移动 11步,当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点。
- 对两个子链表分别排序。
- 将两个排序后的子链表合并,得到完整的排序后的链表。可以使用「合并两个有序链表」的做法,将两个有序的子链表进行合并。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| class Solution {
public ListNode sortList(ListNode head) { return sortList(head, null); }
public ListNode sortList(ListNode head,ListNode tail){ if (head==null){ return head; } if (head.next==tail){ head.next=null; return head; } ListNode slow=head; ListNode fast=head; while (fast!=tail){ slow=slow.next; fast=fast.next; if (fast!=tail){ fast=fast.next; } } ListNode mid=slow; ListNode list1=sortList(head, mid); ListNode list2=sortList(mid, tail); ListNode sorted = merge(list1, list2); return sorted; }
public ListNode merge(ListNode list1,ListNode list2){ ListNode pre=new ListNode(-1); ListNode head=pre; while(list1!=null&&list2!=null){ if (list1.val<list2.val){ pre.next=list1; list1=list1.next; }else { pre.next=list2; list2=list2.next; } pre=pre.next; } if (list1==null){ pre.next=list2; }else { pre.next=list1; } return head.next; } }
|
来源:力扣(LeetCode)
链接:148. 排序链表 - 力扣(LeetCode)