题目:Sort a linked list in O(n log n) time using constant space complexity.
思路:题目要求我们使用常数空间复杂度,时间复杂度为O(nlog(n)). 满足这个时间复杂度的有快速排序,归并排序,堆排序。插入排序时间复杂度为O(n^2). 双向链表用快排比较合适,堆排序也可用于链表,单项链表适合于归并排序。我们就用归并排序的思想来完成链表的排序。
首先是用快慢双指针找到链表中间的位置,然后分成前后端分别递归的归并排序,最后合并。
Attention:
1. 快慢指针找中间节点的方法,是常用方法,要熟练使用。
//将链表分成前后两部分 双指针找到中间节点 ListNode* fast = head; ListNode* slow = head; while(fast->next != NULL && fast->next->next != NULL) { slow = slow->next; fast = fast->next->next; }2. 链表的数据结构是如何实现归并的方法的。定义一个合并后的链表,然后把合适的节点放进去。思想和数组是一样的,只是链表操作不一样。
复杂度:如果这里我们考虑递归的栈空间的话,空间复杂度是O(lg(n))
AC Code:
/** * 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) { if(head == NULL || head->next == NULL) return head; //将链表分成前后两部分 双指针找到中间节点 ListNode* fast = head; ListNode* slow = head; while(fast->next != NULL && fast->next->next != NULL) { slow = slow->next; fast = fast->next->next; } ListNode* head2 = slow->next; slow->next = NULL; ListNode* head1 = head; head1 = sortList(head1); //前半段归并排序 head2 = sortList(head2); //后半段归并排序 return merge(head1, head2); } private: ListNode* merge(ListNode* h1, ListNode* h2) { ListNode* dummyhead = new ListNode(0); ListNode* mlist = dummyhead; while(h1 != NULL && h2 != NULL) { if(h1->val <= h2->val) { mlist->next = h1; h1 = h1->next; } else { mlist->next = h2; h2 = h2->next; } mlist = mlist->next; } if(h1 != NULL) { mlist->next = h1; } if(h2 != NULL) { mlist->next = h2; } return dummyhead->next; } };
[C++]LeetCode: 125 Sort List (归并排序链表)
原文地址:http://blog.csdn.net/cinderella_niu/article/details/43191627