排序链表

在 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

原文地址:https://www.cnblogs.com/wuyouwei/p/11807499.html