• Leetcode面试经典150题-148.排序链表


    题目比较简单,使用链表的归并排序

    解法都在代码里,不懂就留言或者私信

    合并链表部分没怎么加注释,时间实在是不充裕,看不懂的看一下这篇专门讲解合并链表的

    Leetcode面试经典150题-21.合并两个有序链表-CSDN博客

    1. /**
    2. * Definition for singly-linked list.
    3. * public class ListNode {
    4. * int val;
    5. * ListNode next;
    6. * ListNode() {}
    7. * ListNode(int val) { this.val = val; }
    8. * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
    9. * }
    10. */
    11. class Solution {
    12. /**本题采用归并排序的思路:把链表分为左右两个部分,分别进行归并排序
    13. 然后进行两个部分的merge过程,这个过程就是说合并两个有序链表的过程 */
    14. public ListNode sortList(ListNode head) {
    15. ListNode cur = head;
    16. /**找一下tail,这是最容易想到的,反正也就是O(n)的时间复杂度 */
    17. while(cur != null && cur.next != null) {
    18. cur = cur.next;
    19. }
    20. /**cur是最后一个节点,也就是tail */
    21. return mergeSortList(head, cur);
    22. }
    23. /**归并排序head~tail这个区间*/
    24. public ListNode mergeSortList(ListNode head, ListNode tail) {
    25. /**如果区间就一个节点,直接返回 */
    26. if(head == tail) {
    27. return head;
    28. }
    29. /**如果区间有两个节点,直接mergeList*/
    30. if(head.next == tail) {
    31. /**merge之前断开链接,不然就跑不完了 */
    32. head.next = null;
    33. return mergeList(head, tail);
    34. }
    35. /**开始使用快慢指针找中点 */
    36. ListNode slow = head, fast = head;
    37. /**确保fast在head~tail范围内,如果它是tail或者它的next是tail就终止循环 */
    38. while(fast != tail && fast.next != tail) {
    39. /**fast和slow先各走一步 */
    40. slow = slow.next;
    41. /**快指针每次走两步 */
    42. fast = fast.next.next;
    43. }
    44. /**出循环的时候fast是tail或者tail的前一个,然后slow是上班段最后一个节点,断开slow和后面链表的连接
    45. 断开之前先拿到后半段的最后一个节点*/
    46. ListNode rightFirst = slow.next;
    47. slow.next = null;
    48. /**归并排序前半段 */
    49. ListNode list1 = mergeSortList(head, slow);
    50. /**不要管fast,终点是tail*/
    51. ListNode list2 = mergeSortList(rightFirst, tail);
    52. /**合并前后两个有序链表*/
    53. ListNode merged = mergeList(list1, list2);
    54. return merged;
    55. }
    56. /**合并两个有序链表的解法:除了这种方式也可以前面加个dummyNode,这样最后返回dummyNode下一个就行了 */
    57. public ListNode mergeList(ListNode list1, ListNode list2) {
    58. if(list1 == null) return list2;
    59. if(list2 == null) return list1;
    60. ListNode head = list1.val <= list2.val? list1 : list2;
    61. list1 = list1 == head? list1.next : list1;
    62. list2 = list2 == head? list2.next : list2;
    63. ListNode last = head;
    64. while(list1 != null && list2 != null) {
    65. if(list1.val <= list2.val) {
    66. last.next = list1;
    67. last = list1;
    68. list1 = list1.next;
    69. } else {
    70. last.next = list2;
    71. last = list2;
    72. list2 = list2.next;
    73. }
    74. }
    75. /**退出上面的while循环要么是list1用完了,要么是list2用完了,如果某个链表没有用完,就直接串到最后*/
    76. if(list1 != null) {
    77. last.next = list1;
    78. }
    79. if(list2 != null) {
    80. last.next = list2;
    81. }
    82. return head;
    83. }
    84. }

    没有特别好的解法,能过就行吧,时间复杂度都一样

  • 相关阅读:
    基于音频SOC开发板的主动降噪ANC算法源码实现
    java毕业设计独龙族民族特色服务网站Mybatis+系统+数据库+调试部署
    面向6G时代新通信系统的内生感知
    机试算法——基本知识
    基于ssm的房屋租售网站(有报告)。Javaee项目,ssm项目。
    求第n项的因子数量
    2.3 数据库-深入理解
    Win10安装TensorRT
    【SQL SERVER】序列
    【ES6知识】简介、语法变化、解构赋值
  • 原文地址:https://blog.csdn.net/Chang_Yafei/article/details/142281233