首页 > 技术文章 > 排序链表

dataoblogs 2021-04-10 10:08 原文

LeetCode148 排序链表

题目

给定链表的头结点head,返回排序后的链表,按照由小到大的顺序。

  • 案例1

    输入:head = [4,2,1,3]
    输出:[1,2,3,4]

分析

  • 使用归并排序,先找出中间节点(快慢指针:快指针每次走两步,慢指针每次走一步,当快指针走到链表最后,慢指针所在的位置就是中点)。
  • 然后调用递归分解这个链表。
  • 最后合并链表,比较节点的val值大小。

代码实现

 public ListNode sortList(ListNode head) {
        if (head == null || head.next == null) return head;
        //定义快慢指针
        ListNode fast = head.next, slow = head;
        //找出中间节点位置
        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 listNode = new ListNode(0);
        ListNode res = listNode;
        //合并左边部分和右边部分
        while (left!=null&&right!=null){
            if (left.val<right.val){
                listNode.next = left;
                left = left.next;
            }else{
                listNode.next = right;
                right = right.next;
            }
            listNode = listNode.next;
        }
        listNode.next = left!=null?left:right;
        return res.next;

    }

归并排序时间复杂度是O(nlogn)
空间复杂度是O(n)

推荐阅读