LeetCode148. Sort List

女爷i 2022-06-08 12:10 343阅读 0赞

Analysis

This question requires to sort a LinkedList in O(nlogn) time and O(1) space. We know that all comparison-based sorting alrogithm have the upperbound time complexity of O(nlogn). Thus it is obvious that we are looking for some transformation of one of the following algorithms:

Implementation

Merge sort, Quick sort, Heap sort.

Considering we are dealing with a LinkedList and can only use O(1) space, we need to think of which one of the above algorithm can be applied to this situation.

Heap sort is apparently not applicable because of its space complexity.

Quick sort is applicable since, we just need to modify the corresponding partition process of quick sort.

A quick sort implmentation is showed as following.

Note that an important difference of this quick sort with a normal array quick sort is that we have to merge the resulting sub-LinkedList.

  1. class Solution {
  2. public ListNode sortList(ListNode head) {
  3. // When the LinkedList is null or has a length of 1, no need to sort.
  4. if (head == null || head.next == null) {
  5. return head;
  6. }
  7. return quickSort(head);
  8. }
  9. private ListNode quickSort(ListNode head) {
  10. // Base case
  11. if (head == null || head.next == null) {
  12. return head;
  13. }
  14. ListNode fakeSmall = new ListNode(0);
  15. ListNode small = fakeSmall;
  16. ListNode fakeEqual = new ListNode(0);
  17. ListNode equal = fakeEqual;
  18. ListNode fakeLarge = new ListNode(0);
  19. ListNode large = fakeLarge;
  20. // use head as pivot
  21. ListNode curr = head;
  22. while (curr != null) {
  23. if (curr.val > head.val) {
  24. large.next = curr;
  25. large = large.next;
  26. } else if (curr.val < head.val) {
  27. small.next = curr;
  28. small = small.next;
  29. } else {
  30. equal.next = curr;
  31. equal = equal.next;
  32. }
  33. curr = curr.next;
  34. }
  35. small.next = null;
  36. large.next = null;
  37. equal.next = null;
  38. return merge(merge(quickSort(fakeLarge.next), quickSort(fakeSmall.next)), fakeEqual.next);
  39. }

Merge sort is also applicable, we need to change the process of finding middle point and merge. The merge is just the same as Merge 2 sorted LinkedList.

A merge sort implementation is showed as following:

  1. /**
  2. * Definition for singly-linked list.
  3. * public class ListNode {
  4. * int val;
  5. * ListNode next;
  6. * ListNode(int x) { val = x; }
  7. * }
  8. */
  9. class Solution {
  10. public ListNode sortList(ListNode head) {
  11. // When the LinkedList is null or has a length of 1, no need to sort.
  12. if (head == null || head.next == null) {
  13. return head;
  14. }
  15. return mergeSort(head);
  16. }
  17. private ListNode mergeSort(ListNode head) {
  18. /**
  19. * Using merge sort to sort the 2 LinkedList recursively.
  20. */
  21. if (head.next == null) {
  22. return head;
  23. }
  24. // Get the middle point of the LinkedList
  25. ListNode middle = findMiddle(head);
  26. // Sort the first half
  27. ListNode left = mergeSort(head);
  28. // Sort the second half
  29. ListNode right = mergeSort(middle);
  30. return merge(left, right);
  31. }
  32. private ListNode merge(ListNode left, ListNode right) {
  33. // Merge 2 sorted LinkedList
  34. ListNode dummy = new ListNode(0);
  35. ListNode head = dummy;
  36. while (left != null && right != null) {
  37. if (left.val <= right.val) {
  38. head.next = left;
  39. left = left.next;
  40. } else {
  41. head.next = right;
  42. right = right.next;
  43. }
  44. head = head.next;
  45. }
  46. if (left != null) {
  47. head.next = left;
  48. }
  49. if (right != null) {
  50. head.next = right;
  51. }
  52. return dummy.next;
  53. }
  54. private ListNode findMiddle(ListNode head) {
  55. /**
  56. * Find the middle point of a linked list
  57. * And split the original LinkedList into 2 separated List by removing
  58. * the next pointer in the middle.
  59. */
  60. ListNode fast = head;
  61. ListNode slow = head;
  62. while (fast.next != null && fast.next.next != null) {
  63. slow = slow.next;
  64. fast = fast.next.next;
  65. }
  66. ListNode ret = slow.next;
  67. slow.next = null;
  68. return ret;
  69. }
  70. }

发表评论

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

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

相关阅读