Java排序链表

剑指offer 148.排序链表
Java排序链表_第1张图片Java排序链表_第2张图片Java排序链表_第3张图片

解题思路:
由时间复杂度O(nlogn)知道我们可以使用归并排序
归并排序经常会出现在合并两个有序链表这样类似的题中

  1. 定义fast指针和slow指针, 利用fastslow将链表从中点分为两个链表
    ① 对应操作:
    slow = slow.next;
    fast = fast.next.next;
    此时slow指针刚好停在链表的中点
    将链表从中间断开的操作:
    slow.next = null;
    此时左右两个断开的链表的第一个节点分别为headtmp

  2. 对左右两个断开的链表递归进行如下操作
    操作为:
    ListNode left = sortList(head);
    ListNode right = sortList(tmp);
    递归终止条件: head.next = null;, 意味着只剩下一个节点

  3. 将两个排序链表合并, 合并为一个排序链表
    创建一个傀儡节点dum
    创建指针left和指针right, 分别指向左右两个链表的头部, 比较两指针处节点值大小, 由小到大加入合并链表头部, 指针交替前进, 直至添加完两个链表
    返回傀儡节点的下一个节点
    即:
    return res.next;

class Solution {
    public ListNode sortList(ListNode head) {
        if(head == null || head.next == null) return head;
        ListNode slow = head, fast = head.next;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode tmp = slow.next;
        slow.next = null;
        ListNode left = sortList(head);
        ListNode right = sortList(tmp);
        ListNode dum = new ListNode(0, head);
        ListNode res = dum;
        while(left != null && right != null){
            if(left.val > right.val){
                dum.next = right;
                right = right.next;
            }else{
                dum.next = left;
                left = left.next;
            }
            dum = dum.next;
        }
        dum.next = left != null ? left : right;
        return res.next;
    }
}

你可能感兴趣的:(剑指offer,链表,java,归并排序)