您的位置:首页 > 其它

LeetCode 148. Sort List

2018-01-21 18:21 316 查看

问题描述

https://leetcode.com/problems/sort-list/description/

Sort a linked list in O(n log n) time using constant space complexity.

使用空间复杂度为常量,时间复杂度为 O(nlgn)对链表进行排序。

问题分析

排序的算法复杂度为O(nlgn)的有三种,快速排序,堆排序,归并排序。这里使用归并排序。

三步:

将当前链表一分为二,取得中间节点。其中需要注意的是,如果长度是奇数,中间那个节点在左边。

对左边和右边的链表进行排序。

归并两个有序链表。

算法实现

/**
* 使用常数空间
* 和O(nlgn)的时间复制度来对链表进行排序
* 归并排序
* 先逐步的将节点进行  两两排序。然后合并,最后到所有的排序。
* 归并排序:见过一个数组分为两部;对这两部分分别排序;归并排好序的数组。
* 0,21,15,
* 24,3,13
*
* @param head
* @return
*/
public ListNode sortList(ListNode head) {

if (head == null || head.next == null) {
return head;
}

ListNode leftHead = head;
ListNode rightHead = getMiddle(head);

leftHead = sortList(leftHead);
rightHead = sortList(rightHead);
return merge(leftHead, rightHead);

}

/**
* 将两个量表合并在一起,以leftHead为头部
*
* @param leftHead
* @param rightHead
*/
protected ListNode merge(ListNode leftHead, ListNode rightHead) {

ListNode head = new ListNode(0);
ListNode helper = head;
ListNode leftPoint = leftHead;
ListNode rightPoint = rightHead;
ListNode temp = null;

while (leftPoint != null && rightPoint != null) {
if (leftPoint.val < rightPoint.val) {
temp = leftPoint;
leftPoint = leftPoint.next;
} else {
temp = rightPoint;
rightPoint = rightPoint.next;
}
helper.next = temp;
helper = temp;
}

if (leftPoint != null) {
helper.next = leftPoint;
}
if (rightPoint != null) {
helper.next = rightPoint;
}
return head.next;
}

/**
* 返回一个链表的中间节点.同时需要将两个数组给阶段开来
* <p>
* 如果奇数,前面的数需要多放置一个,后面的节点数要少
*
* @param head
* @return
*/
protected ListNode getMiddle(ListNode head) {

if (head == null) {
return null;
}

ListNode fast = head.next;
ListNode slow = head.next;
ListNode pre = head;
while (true) {
if (fast != null) {
fast = fast.next;
} else {
break;
}
if (fast != null) {
fast = fast.next;
} else {
break;
}
pre = slow;
slow = slow.next;
}
pre.next = null;
return slow;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: