• 排序链表


    在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

    示例 1:

    输入: 4->2->1->3
    输出: 1->2->3->4
    示例 2:

    输入: -1->5->3->4->0
    输出: -1->0->3->4->5

    解法1:

    public static ListNode sortList(ListNode head) {
        /*定义当前指针*/
        ListNode cur = head;
        /*链表数量*/
        int count = 0;
        ListNode countNode = head;
        /*计算链表数量*/
        while (countNode != null) {
          count++;
          countNode = countNode.next;
        }
        /*计算新的链表数量*/
        int length = count / 2 + count % 2;
        ListNode[] nodes = new ListNode[length];
        int co = 0;
        /*把链表2个节点排序形成新的链表放入一个链表数组中*/
        while (cur != null && cur.next != null) {
          ListNode tmp = cur.next;
          ListNode tmp1 = cur;
          ListNode tmp2 = cur.next.next;
          tmp.next = null;
          tmp1.next = null;
          if (tmp1.val > tmp.val) {
            tmp.next = tmp1;
            nodes[co] = tmp;
          } else {
            tmp1.next = tmp;
            nodes[co] = tmp1;
          }
          co++;
          cur = tmp2;
        }
        /*防止奇数个时元素没放入*/
        if (cur != null) {
          nodes[length - 1] = cur;
        }
        /*合并*/
        return mergeList(nodes);
      }
    
      public static ListNode mergeList(ListNode[] lists) {
        /*计算新的数组大小*/
        int count = lists.length / 2 + lists.length % 2;
        /*如果数组里的元素为0返回null*/
        if (count == 0) {
          return null;
        }
        /*链表两两合并后放入新的链表数组中*/
        ListNode[] newLists = new ListNode[count];
        for (int i = 0; i < lists.length; i = i + 2) {
          if (lists.length <= i + 1) {
            newLists[count - 1] = lists[i];
            break;
          }
          newLists[i / 2] = merge(lists[i], lists[i + 1]);
        }
        /*如果新链表数组的元素大于1递归调用*/
        if (newLists.length > 1) {
          return mergeList(newLists);
        }
        /*返回结果*/
        return newLists.length == 0 ? null : newLists[0];
      }
    
      /**
       * 合并2个有序链表
       *
       * @param l1
       * @param l2
       * @return
       */
      public static ListNode merge(ListNode l1, ListNode l2) {
        /*定义一个哑节点*/
        ListNode dumb = new ListNode(0);
        /*定义一个节点赋值为哑节点*/
        ListNode head = dumb;
        /*当2个链表都不为空时继续遍历*/
        while (l1 != null && l2 != null) {
          /*如果l1的值小于l2的值,则dumb的下一个指向l1,l1移向自己的下一位*/
          if (l1.val < l2.val) {
            dumb.next = l1;
            l1 = l1.next;
          } else {
            /*如果l1的值大于l2的值,则dumb的下一个指向l2,l2移向自己的下一位*/
            dumb.next = l2;
            l2 = l2.next;
          }
          /*哑节点移向自己的下一位*/
          dumb = dumb.next;
        }
        /*防止l1和l2肯定有一个不为null,所以需要拼接没遍历完的*/
        dumb.next = (l1 == null ? l2 : l1);
        return head.next;
      }
    View Code

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/sort-list

  • 相关阅读:
    分享一个MySQL分库分表备份脚本(原)
    mysql配置以及性能优化(转)
    redis 集群配置实战
    Debian安装fail2ban来防止扫描
    关于微信小程序,一些想法
    读书笔记:《HTML5开发手册》-- 现存元素的变化
    linux下如何使用vnstat查看服务器带宽流量统计
    在iOS微信浏览器中自动播放HTML5 audio(音乐)的2种正确方式
    VS自定义项目模板:[4]自定义模板的分组
    VS自定义项目模板:[3]创建自定义模板
  • 原文地址:https://www.cnblogs.com/wuyouwei/p/11807499.html
Copyright © 2020-2023  润新知