LeetCode148—Sort List

素颜马尾好姑娘i 2022-07-15 03:16 275阅读 0赞

原题

原题链接

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

Subscribe to see which companies asked this question

分析

O(nlogn) 时间复杂度的排序就那么几种,快排、归并排序、堆排序。这题我用归并排序。

归并排序的思路是分而治之,传统在以数组或容器作为数据结构的归并排序算法中,我们可以用左右边界的索引来对待排序列不断的向下“分”,显然索引访问在链表这里就行不通了。

如何对链表进行“分” 操作?
1.找到链表的中点(节点个数为偶数时使用返回靠左的节点作为中点返回)。
2.记录中点节点的下一个位置(作为右半序列的头指针)
3.将中点的next置为NULL,这样原链表就被砍成两节了。
4.循环进行前3步,直到链表被打散成一个一个的节点。

上述四步就完成了分操作,接下来要合并,也就是排序:
这一步就简单了,其本质就是将两个有序链表合并到一个有序链表中去。

代码

  1. class Solution {
  2. private:
  3. ListNode* findMid(ListNode* list);
  4. ListNode* MergeSort(ListNode* list);
  5. ListNode* Merge(ListNode* left,ListNode*right);
  6. public:
  7. ListNode* sortList(ListNode* head) {
  8. return MergeSort(head);
  9. }
  10. };
  11. ListNode* Solution::findMid(ListNode *list)
  12. {
  13. if(NULL==list)
  14. return list;
  15. ListNode* slow=list;
  16. ListNode* quick=list->next;
  17. while(quick&&quick->next)
  18. {
  19. slow=slow->next;
  20. quick=quick->next->next;
  21. }
  22. return slow;
  23. }
  24. ListNode* Solution::MergeSort(ListNode* list)
  25. {
  26. if(list==NULL||list->next==NULL)
  27. return list;
  28. ListNode* mid = findMid(list);
  29. ListNode* right=mid->next;
  30. mid->next=NULL;
  31. list=MergeSort(list);
  32. right=MergeSort(right);
  33. return Merge(list,right);
  34. }
  35. ListNode* Solution::Merge(ListNode*left,ListNode*right)
  36. {
  37. ListNode* result=new ListNode(0);
  38. ListNode * p=result;
  39. while(left&&right)
  40. {
  41. if(left->val<=right->val)
  42. {
  43. p->next=left;
  44. p=left;
  45. left=left->next;
  46. }
  47. else
  48. {
  49. p->next=right;
  50. p=right;
  51. right=right->next;
  52. }
  53. }
  54. if(NULL!=left)
  55. p->next=left;
  56. if(NULL!=right)
  57. p->next=right;
  58. return result->next;
  59. }

发表评论

表情:
评论列表 (有 0 条评论,275人围观)

还没有评论,来说两句吧...

相关阅读