148.排序链表
1.题目描述
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序
2.解题报告
针对nlogn的排序算法,主要有快速排序,归并排序和堆排序。其中,堆排序利用了数组的连续特性。所以这里不能采用。其次,在快速排序中,设计大量数字的交换且单链表因为只能单向遍历,使用partition不是很直观。
所以,本题采用归并排序链表版来实现。
具体思路如下:
1.使用快慢指针,找到链表的中点。
2.对链表的前半部分和后半部分分别排序。
3.将两部分合并。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode* head) {
return sortList(head, NULL);
}
private:
// sort [beg, end), and return new head, and tail->next = end;
ListNode* sortList(ListNode*beg, ListNode* end) {
if (beg == end || !beg || beg->next == end) {
return beg;
}
// at least has two node
// [head, mid, end], maybe head == mid == end
// [head, mid) < mid < [mid->next, end)
ListNode* head = NULL; // new head
ListNode* mid = NULL;
beg = partition(beg, end, &head, &mid);
// sort [mid->next, end)
if (mid && mid->next != end) {
mid->next = sortList(mid->next, end);
}
// sort [head, mid)
return sortList(head, mid);
}
ListNode* partition(ListNode* beg, ListNode* end,
ListNode** p_head, ListNode** p_mid) {
if (!beg || !p_head || !p_mid) {
return beg;
}
ListNode* mid = beg;
ListNode* tail1 = NULL;
ListNode* tail2 = NULL;
int v = mid->val;
ListNode* p = mid->next;
while (p != end) {
if (p->val < v) {
if (!*p_head) {
*p_head = p;
tail1 = p;
} else {
tail1->next = p;
tail1 = p;
}
} else {
if (!tail2) {
mid->next = p;
tail2 = p;
} else {
tail2->next = p;
tail2 = p;
}
}
p = p->next;
}
if (tail1) { tail1->next = mid; }
else { *p_head = mid; }
if (tail2) { tail2->next = end; }
else { mid->next = end; }
*p_mid = mid;
return *p_head;
}
};
3. 最佳答案
c答案
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
//head不参与排序!
void mergeSortList(struct ListNode* head) {
struct ListNode* slow, *fast,*pre;
if (NULL == head)
return; //无效输入
else{
struct ListNode R;
slow = fast = head;
do {
if ((fast = fast->next) != NULL) {
fast = fast->next;
slow = slow->next;
}
} while (fast);
if (NULL == slow->next)return; //只有0或1个元素
R.next = slow->next;
slow->next = NULL; //一分为二
mergeSortList(head); //使左半有序
mergeSortList(&R); //使右半有序
slow = head->next; fast = R.next; //两边准备进行归并
}
pre = head; //尾插法(是slow的前驱)
do {
if (fast->val < slow->val) { //右边比左边小
pre = pre->next = fast; //原pre->next==slow,所以不会丢链
fast = fast->next;
pre->next = slow; //还原pre是slow的前驱
if (fast == NULL)
break; //左边的pre本来就接着slow,无需处理
}
else { //左边小
pre = slow;
slow = slow->next;
if (slow == NULL) {
pre->next = fast; //剩余的右边接到左边
break;
}
}
} while (true);
}
struct ListNode* sortList(struct ListNode* head) {
struct ListNode Head; Head.next = head; //真正头结点,不参与排序
mergeSortList(&Head);
return Head.next;
}
c++答案
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode * merge(ListNode* left, ListNode* right)
{
ListNode* newhead = NULL, *pre=NULL;
while (left && right)
{
if (left->val < right->val)
{
if (!newhead)
{
newhead = pre = left;
left = left->next;
}
else
{
pre->next = left;
pre = pre->next;
left = left->next;
}
}
else
{
if (!newhead)
{
newhead = pre = right;
right = right->next;
}
else
{
pre->next = right;
pre = pre->next;
right = right->next;
}
}
}
while (left)
{
pre->next = left;
left = left->next;
pre = pre->next;
}
while (right)
{
pre->next = right;
right = right->next;
pre = pre->next;
}
pre->next = NULL;
return newhead;
}
ListNode* sortList(ListNode* head) {
if (head == NULL || head->next == NULL)
return head;
else
{
ListNode* slow = head, *fast = head->next;
while (fast != NULL && fast->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
}
ListNode* temp = slow->next;
slow->next = NULL;
ListNode* l = sortList(head);
ListNode* r = sortList(temp);
return merge(l, r);
}
}
};
java答案
/**
* 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 fast = head;
ListNode slow = head;
// 快慢指针寻找链表的中间节点
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
// 把链表分为两段
ListNode l1 = head;
ListNode l2 = slow.next;
slow.next = null;
// Merge Sort
l1 = sortList(l1);
l2 = sortList(l2);
return merge(l1, l2);
}
// 归并两个已经排好序的链表
private ListNode merge(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
ListNode dummy = new ListNode(-1);
ListNode cur = dummy;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
cur.next = l1;
l1 = l1.next;
} else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
if (l1 != null) cur.next = l1;
else cur.next = l2;
return dummy.next;
}
}
JavaScript答案
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var merge = function(l1,l2) {
var l = new ListNode();
var p = l;
while(l1 && l2) {
if(l1.val < l2.val) {
p.next = l1;
l1 = l1.next
} else {
p.next = l2;
l2 = l2.next
}
p = p.next
}
if(l1) {
p.next = l1;
}
if(l2) {
p.next = l2;
}
return l.next;
}
var sortList = function(head) {
if(head === null || head.next === null) {
return head;
}
var slow = head;
var fast = head;
var prev = null;
while(fast && fast.next) {
prev = slow
fast = fast.next.next;
slow = slow.next
}
prev.next = null;
return merge(sortList(head), sortList(slow));
};
c#答案
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode SortList(ListNode head) {
if(head == null) return head;
ListNode now = head;
List list = new List();
while(now != null)
{
list.Add(now.val);
now = now.next;
}
list.Sort();
int length = list.Count;
ListNode result = new ListNode(list[0]);
now = result;
for(int i=1;i
python2.x答案
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def sortList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
node = head
res=[]
while node:
res.append(node.val)
node = node.next
res.sort()
if not res:
return None
newhead = ListNode(res[0])
cur_Node = newhead
for i,v in enumerate(res):
if i == 0:
continue
obj = ListNode(v)
cur_Node.next=obj
cur_Node=obj
return newhead
python3.x答案
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def sortList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head: return None
res = []
while head:
res.append(head)
head = head.next
res.sort(key = lambda ele: ele.val)
temp = res[0]
for i in range(1,len(res)):
temp.next = res[i]
temp = res[i]
res[-1].next = None
return res[0]
go答案
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func sortList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
middle := split(head)
return merge(sortList(head), sortList(middle))
}
// 双指针切分list
func split(head *ListNode) *ListNode {
slow, fast := head, head
var tail *ListNode
for fast != nil && fast.Next != nil {
tail = slow
slow = slow.Next
fast = fast.Next.Next
}
tail.Next = nil
return slow
}
func merge(left ,right *ListNode) *ListNode {
var head, cur, pre *ListNode
for left != nil && right != nil {
if left.Val < right.Val {
cur = left
left = left.Next
} else {
cur = right
right = right.Next
}
// 生成head
if head == nil {
head = cur
} else {
pre.Next = cur
}
pre = cur
}
if left == nil {
pre.Next = right
} else {
pre.Next = left
}
return head
}