-- 关键字:链表、归并排序
-- 难度:Medium
-- 题目大意:对一个链表排序,时间复杂度:O(NlogN) ,空间复杂度:O(1)
题目:
Sort a linked list in O(n log n) time using constant space complexity.
Example 1:
Input: 4->2->1->3
Output: 1->2->3->4
Example 2:
Input: -1->5->3->4->0
Output: -1->0->3->4->5
解题思路:回想排序算法,线性对数时间复杂度的有:快速排序,堆排序,归并排序,前两种暂时没实现,利用归并排序先实现了:时间复杂度:O(nlgn) 空间:O(lgn) 用了递归,递归栈占用空间O(lgn),是不符合题意的,先当作本题1.0版本,基本思路:使用快慢指针将链表分成两部分,递归进行下去,然后合并排好序的两个链表。
AC代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
if(head==null||head.next==null) return head;
ListNode dummy = new ListNode(0);
ListNode pre = dummy;
dummy.next = head;
ListNode slow = head;
ListNode fast = head;
//使用快慢指针切分链表
while(fast!=null&&fast.next!=null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
}
pre.next = null; // 注意此处要设为null
ListNode l1 = sortList(head);
ListNode l2 = sortList(slow);
return merge(l1, l2);
}
// 合并两个有序的链表
public ListNode merge(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode head = dummy;
while(l1!=null&&l2!=null) {
if(l1.val<l2.val) {
dummy.next = l1;
dummy = dummy.next;
l1 = l1.next;
}
else {
dummy.next = l2;
dummy = dummy.next;
l2 = l2.next;
}
}
if(l1!=null) {
dummy.next = l1;
}
if(l2!=null) {
dummy.next = l2;
}
return head.next;
}
}
网友评论