leetCode 148 排序链表

题目描述:

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

示例输入输出:

leetCode 148 排序链表 - 图1
leetCode 148 排序链表 - 图2

思路:

归并排序

  • 利用归并排序,首先把一个未排序的序列从中间分割成2部分,再把2部分分成4部分,依次分割下去,直到分割成一个一个的数据,再把这些数据两两归并到一起,使之有序,不停的归并,最后成为一个排好序的序列。
  • 参数:
    • 链表头节点head
  • 流程:
    • 通过快慢指针找到链表中间节点mid
    • 归并流程:
      • 结束条件:
        • 判断tempList的长度是否等于nums.length如果是,将tempList加入结果集,结束递归。
      • 要做的事:
        • 建立一个for循环:
          • 将nums的每个元素分别加入temp中。
          • 如果元素位置的visited已被标记为true,遍历下一个。
          • 没有被标记,则在visited标记此数。
          • tempList加入此数。
          • 递归。
          • 将visited的标记去掉。
          • 从temp中将此数移除。
  • 复杂度分析:
    • 时间复杂度:O(n*n!)
    • 空间复杂度:O(n)
  • 代码:
    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. public ListNode sortList(ListNode head) {
    13. if (head == null || head.next == null)
    14. return head;
    15. ListNode fast = head.next, slow = head;
    16. while (fast != null && fast.next != null) {
    17. slow = slow.next;
    18. fast = fast.next.next;
    19. }
    20. ListNode tmp = slow.next;
    21. slow.next = null;
    22. ListNode left = sortList(head);
    23. ListNode right = sortList(tmp);
    24. ListNode h = new ListNode(0);
    25. ListNode res = h;
    26. while (left != null && right != null) {
    27. if (left.val < right.val) {
    28. h.next = left;
    29. left = left.next;
    30. } else {
    31. h.next = right;
    32. right = right.next;
    33. }
    34. h = h.next;
    35. }
    36. h.next = left != null ? left : right;
    37. return res.next;
    38. }
    39. }