题目链接:https://leetcode.com/problems/sort-list/
题目:
Sort a linked list in O(n log n) time using constant space complexity.
解题思路:
排序 + O(n log n) = 快速排序,归并排序,堆排序
这道题选用归并排序。
1. 先将链表从中间拆分为两个子链表(用 walker 和 runner 方法找到链表中点)
2. 递归两个子链表,递归终止条件为链表中元素的个数 <= 2
3. 对两个子链表进行归并排序
4. 为了方便链表的操作,在归并时新增一个头结点,将结点归并到头结点的后面
大神的思路是相同的,但他的代码实现比我的快一点,也附上他的代码
http://blog.youkuaiyun.com/linhuanmars/article/details/21133949
代码实现:
自己的实现:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode sortList(ListNode head) {
if(head == null || head.next == null)
return head;
return helper(head);
}
ListNode helper(ListNode head) {
if(head.next == null)
return head;
ListNode l1 = head;
ListNode l2 = head.next;
if(head.next.next != null) { // 找链表中点,将链表对半拆开进行递归
ListNode walker = head.next;
ListNode runner = head.next.next;
while(runner.next != null && runner.next.next != null) {
walker = walker.next;
runner = runner.next.next;
}
ListNode q = walker.next;
walker.next = null;
l1 = helper(head);
l2 = helper(q);
}
ListNode tmpH = new ListNode(0); // 启用头结点,方便操作
ListNode p = tmpH;
if(l1.next == l2 && l2.next == null) // 归并的两个链表是两个结点
l1.next = null;
while(l1 != null && l2 != null) { // 对两个链表进行归并
ListNode tmp1 = l1.next;
ListNode tmp2 = l2.next;
if(l1.val <= l2.val) {
p.next = l1;
l1 = tmp1;
} else {
p.next = l2;
l2 = tmp2;
}
p = p.next;
}
while(l1 != null) {
p.next = l1;
l1 = l1.next;
p = p.next;
}
while(l2 != null) {
p.next = l2;
l2 = l2.next;
p = p.next;
}
p.next = null;
return tmpH.next;
}
}
15 / 15 test cases passed.
Status: Accepted
Runtime: 9 ms
大神的实现:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode sortList(ListNode head) {
return mergeSort(head);
}
private ListNode mergeSort(ListNode head)
{
if(head == null || head.next == null)
return head;
ListNode walker = head;
ListNode runner = head;
while(runner.next!=null && runner.next.next!=null)
{
walker = walker.next;
runner = runner.next.next;
}
ListNode head2 = walker.next;
walker.next = null;
ListNode head1 = head;
head1 = mergeSort(head1);
head2 = mergeSort(head2);
return merge(head1, head2);
}
private ListNode merge(ListNode head1, ListNode head2)
{
ListNode helper = new ListNode(0);
helper.next = head1;
ListNode pre = helper;
while(head1!=null && head2!=null)
{
if(head1.val<head2.val)
{
head1 = head1.next;
}
else
{
ListNode next = head2.next;
head2.next = pre.next;
pre.next = head2;
head2 = next;
}
pre = pre.next;
}
if(head2!=null)
{
pre.next = head2;
}
return helper.next;
}
}
15 / 15 test cases passed.
Status: Accepted
Runtime: 8 ms