赞
踩
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
输入: 4->2->1->3
输出: 1->2->3->4
输入: -1->5->3->4->0
输出: -1->0->3->4->5
题目所要求的排序时间复杂度为O(n log n) 并且空间复杂度为常数级,选归并排序,对于数组的归并排序需要的空间复杂度为O(n),但是对于链表每次存储一组链表只需要存贮 头节点的地址即可,故空间复杂度为O(1)。
以下是归并排序算法代码:
class Solution { public: ListNode* sortList(ListNode* head) { if(head == NULL || head->next == NULL) //递归出口 return head; ListNode* head1 = head; ListNode* head2 = getMiddle(head); head1 = sortList(head1); //对前半段进行递归 head2 = sortList(head2); //对后半段进行递归 return merge(head1, head2); } //归并 ListNode* merge(ListNode* head1, ListNode* head2){ ListNode* dummyHead = new ListNode(-1); ListNode* cur = dummyHead; while(head1 != NULL && head2 != NULL){ if(head1->val > head2->val){ cur->next = head2; head2 = head2->next; } else{ cur->next = head1; head1 = head1->next; } cur = cur->next; } if(head1 == NULL) cur->next = head2; if(head2 == NULL) cur->next = head1; return dummyHead->next; } //获取链表中间位置,并将链表从中间分为两个链表 ListNode* getMiddle(ListNode* head){ //使用快慢节点方法寻找链表的中间节点 ListNode *fast = head, *slow = head; while(fast != NULL && fast->next != NULL && fast->next->next != NULL){ slow = slow->next; fast = fast->next->next; } fast = slow; slow = slow->next; //第二个链表的首节点 fast->next = NULL; //将原来的链表从中间断开 return slow; } };
程序耗时:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。