leetCode解题报告之Sort List

你的名字 2022-08-25 15:55 178阅读 0赞

勉励自己:坚持,谁说做工程的人不能学好算法!为面试做准备,加油!!!!!

题目:

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

分析:

题目要求我们要用一个复杂度O(nlogn)的排序算法来排序一个链表,复杂度O(nlogn)的排序算法包括:快速排序,堆排序,希尔排序,二叉排序树排序,归并排序

情况:

考虑到题目的要求,我个人觉得用“归并排序”会比较好!

第一次提交没AC的Time Limit Exceeded代码:(没有考虑到两个递归之后的子链表做排序的话,关于合并的时间消耗)

  1. package cn.xym.leetcode.sortlist;
  2. public class Solution1 {
  3. public ListNode sortList(ListNode head) {
  4. if (head == null || head.next == null)
  5. return head;
  6. int len = getListSize(head);
  7. mergerSort(head, 0, len-1);
  8. return head;
  9. }
  10. public void mergerSort(ListNode head, int left, int right){
  11. int mid = (right+left) / 2;
  12. if (left == right)
  13. return;
  14. else{
  15. int first = left;
  16. int last = right;
  17. mergerSort(head, first, mid);
  18. mergerSort(head, mid+1, last);
  19. mergerListNode(head, first, mid, last);
  20. }
  21. }
  22. public void mergerListNode(ListNode head, int left,int mid,int right){
  23. int left1 = 0;
  24. int right1 = mid - left;
  25. int left2 = 0;
  26. int right2 = right - mid - 1;
  27. int k = 0;
  28. ListNode node1 = getListNode(head, left);
  29. ListNode node2 = getListNode(head, mid+1);
  30. int[] temp = new int[right - left + 1];
  31. while (left1 <= right1 && left2 <= right2){
  32. ListNode temp1 = getListNode(node1, left1);
  33. ListNode temp2 = getListNode(node2, left2);
  34. if (temp1.val < temp2.val){
  35. temp[k++] = temp1.val;
  36. left1++;
  37. }else{
  38. temp[k++] = temp2.val;
  39. left2++;
  40. }
  41. }
  42. while (left1 <= right1){
  43. temp[k++] = getListNode(node1, left1).val;
  44. left1++;
  45. }
  46. while (left2 <= right2){
  47. temp[k++] = getListNode(node2, left2).val;
  48. left2++;
  49. }
  50. for (int i=0; i<k; ++i){
  51. getListNode(head, i + left).val = temp[i];
  52. }
  53. }
  54. public ListNode getListNode(ListNode head, int index){
  55. ListNode temp = head;
  56. for (int i=0; i<index; ++i){
  57. temp = temp.next;
  58. }
  59. return temp;
  60. }
  61. public int getListSize(ListNode head){
  62. int len = 0;
  63. while (head != null){
  64. len++;
  65. head = head.next;
  66. }
  67. return len;
  68. }
  69. public static void main(String[] args) {
  70. ListNode head1 = new ListNode(10);
  71. ListNode head2 = new ListNode(40);
  72. ListNode head3 = new ListNode(6);
  73. ListNode head4 = new ListNode(22);
  74. ListNode head5 = new ListNode(1);
  75. ListNode head6 = new ListNode(30);
  76. head1.next = head2;
  77. head2.next = head3;
  78. head3.next = head4;
  79. head4.next = head5;
  80. head5.next = head6;
  81. head6.next = null;
  82. Solution1 solution = new Solution1();
  83. solution.sortList(head1);
  84. while (head1 != null){
  85. System.out.println(head1.val);
  86. head1 = head1.next;
  87. }
  88. }
  89. }

下面是AC的代码:

  1. package cn.xym.leetcode.sortlist;
  2. class ListNode {
  3. int val;
  4. ListNode next;
  5. ListNode(int x) {
  6. val = x;
  7. next = null;
  8. }
  9. }
  10. public class Solution {
  11. public ListNode sortList(ListNode head) {
  12. if (head == null || head.next == null)
  13. return head;
  14. int len = getSize(head);
  15. ListNode list = mergerSort(head,len);
  16. return list;
  17. }
  18. public ListNode mergerSort(ListNode head, int len) {
  19. if (len == 1)
  20. return head;
  21. //找出当前head链表中间的ListNode
  22. int middle = len / 2;
  23. ListNode preMiddleNode = getListNode(head, middle-1);
  24. ListNode endNode = getListNode(head, len-1);
  25. ListNode middleNode = preMiddleNode.next;
  26. preMiddleNode.next = null;
  27. endNode.next = null;
  28. int leftLen = getSize(head);
  29. int rightLen = getSize(middleNode);
  30. ListNode leftList = mergerSort(head, leftLen);
  31. ListNode rightList = mergerSort(middleNode, rightLen);
  32. ListNode allList = mergerListNode(leftList, rightList);
  33. return allList;
  34. }
  35. /*返回一个局部排序好的表*/
  36. public ListNode mergerListNode(ListNode left, ListNode right) {
  37. ListNode temp = new ListNode(Integer.MIN_VALUE);
  38. ListNode preHead = new ListNode(Integer.MIN_VALUE);
  39. preHead = temp;
  40. //两个排序好的链表进行合并
  41. while (left != null && right != null){
  42. if (left.val < right.val){
  43. temp.next = left;
  44. left = left.next;
  45. }else{
  46. temp.next = right;
  47. right = right.next;
  48. }
  49. temp = temp.next;
  50. }
  51. if (left == null){
  52. temp.next = right;
  53. }
  54. if (right == null){
  55. temp.next = left;
  56. }
  57. return preHead.next;
  58. }
  59. public ListNode getListNode(ListNode head, int index) {
  60. ListNode temp = head;
  61. for (int i = 0; i < index; ++i) {
  62. temp = temp.next;
  63. }
  64. return temp;
  65. }
  66. public int getSize(ListNode head) {
  67. int len = 0;
  68. while (head != null) {
  69. len++;
  70. head = head.next;
  71. }
  72. return len;
  73. }
  74. public static void main(String[] args) {
  75. ListNode head1 = new ListNode(10);
  76. ListNode head2 = new ListNode(40);
  77. ListNode head3 = new ListNode(6);
  78. ListNode head4 = new ListNode(22);
  79. ListNode head5 = new ListNode(1);
  80. ListNode head6 = new ListNode(30);
  81. head1.next = head2;
  82. head2.next = head3;
  83. head3.next = head4;
  84. head4.next = head5;
  85. head5.next = head6;
  86. head6.next = null;
  87. Solution solution = new Solution();
  88. head1 = solution.sortList(head1);
  89. while (head1 != null) {
  90. System.out.println(head1.val);
  91. head1 = head1.next;
  92. }
  93. }
  94. }

发表评论

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

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

相关阅读