• LeetCode148.排序链表


    看完题目的想法是,直接把所有节点的值都遍历出来放进优先队列里面,然后从头节点遍历一次,每次把优先队列poll()的值赋给节点的val即可,说实话,想完还觉得估计有问题怎么可能这么简单,但是不管了,5分钟就把这个算法写出来了,一提交,居然通过了!以下是我的代码:

    1. class Solution {
    2. public ListNode sortList(ListNode head) {
    3. PriorityQueue pri = new PriorityQueue<>(new Comparator(){
    4. public int compare(Integer e1, Integer e2){
    5. return e1 - e2;
    6. }
    7. });
    8. ListNode h = head;
    9. while(h != null){
    10. pri.add(h.val);
    11. h = h.next;
    12. }
    13. ListNode h2 = head;
    14. while(h2 != null){
    15. h2.val = pri.poll();
    16. h2 = h2.next;
    17. }
    18. return head;
    19. }

    其实这个优先队列也不用new一个比较器实例,因为默认是从小到大的。然后看看官方题解吧,不要用我这种二流子写法了。

    题解用的是归并排序,先把链表分成两半,每半分别排序,然后再把排完序的两半合并起来;对于两半中的每一半也是这样的,把这半再分成两半,两半分别排好序合起来,只有当“一半”只有两个节点是不用再分,直接比较这两个节点然后排序,然后再与另一半合起来,然后再与更大的另一半合起来...一直合到这个完整的最大的链表。

    分割可以采用快慢指针的方法,快慢指针同时从头节点出发,快指针每次走两步,慢指针每次走一步,当快指针到达链尾,慢指针就在中间节点。然后利用递归的方法不断的分割链表,直到只剩两个节点,开始合并。

    合并先创建一个哑节点,然后分别比较左右两个链表的头节点,最小的先移到哑节点后面,然后这个链表的指针移到下一个节点,下次比较就是这个链表的第2个节点和另一个链表的第一个节点,(因为两个链表都是已经排好序的,所以每次只要比较两个链表未放进去的最小节点即可),如果一个链表已经遍历完了,只要把另一个链表剩下的部分直接挂在后面即可。

    以下是题解代码:

    1. class Solution {
    2. public ListNode sortList(ListNode head) {
    3. return sortList(head, null);
    4. }
    5. public ListNode sortList(ListNode head, ListNode tail) {
    6. if (head == null) {
    7. return head;
    8. }
    9. if (head.next == tail) {
    10. head.next = null;
    11. return head;
    12. }
    13. ListNode slow = head, fast = head;
    14. while (fast != tail) {
    15. slow = slow.next;
    16. fast = fast.next;
    17. if (fast != tail) {
    18. fast = fast.next;
    19. }
    20. }
    21. ListNode mid = slow;
    22. ListNode list1 = sortList(head, mid);
    23. ListNode list2 = sortList(mid, tail);
    24. ListNode sorted = merge(list1, list2);
    25. return sorted;
    26. }
    27. public ListNode merge(ListNode head1, ListNode head2) {
    28. ListNode dummyHead = new ListNode(0);
    29. ListNode temp = dummyHead, temp1 = head1, temp2 = head2;
    30. while (temp1 != null && temp2 != null) {
    31. if (temp1.val <= temp2.val) {
    32. temp.next = temp1;
    33. temp1 = temp1.next;
    34. } else {
    35. temp.next = temp2;
    36. temp2 = temp2.next;
    37. }
    38. temp = temp.next;
    39. }
    40. if (temp1 != null) {
    41. temp.next = temp1;
    42. } else if (temp2 != null) {
    43. temp.next = temp2;
    44. }
    45. return dummyHead.next;
    46. }
    47. }

  • 相关阅读:
    MDM数据质量应用说明
    股票和期货的区别(股指期货1个点赚多少钱)
    java毕业设计驾考预约系统mybatis+源码+调试部署+系统+数据库+lw
    solidity实战练习2--ERC20实现
    IOS使用Unity容器动态加载3D模型
    Qt QPen
    proguard 混淆jar内容
    《算法竞赛进阶指南》破坏正方形
    CMake error “include could not find load file: FetchContent“
    33李沐动手学深度学习v2/残差网络,ResNet
  • 原文地址:https://blog.csdn.net/qq_61009660/article/details/134289741