148. 排序链表

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

进阶:

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

示例 1:
在这里插入图片描述
输入:head = [4,2,1,3]
输出:[1,2,3,4]
示例 2:
在这里插入图片描述
输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]
示例 3:

输入:head = []
输出:[]

思路- 迭代+拆分+归并

  • 按1 2 4…步长归并
  • 迭代拆分逐块归并,再将每一块拼接
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode sortList(ListNode head) {
        int len=getLength(head);
        //亚节点标记头
        ListNode dHead=new ListNode(-1);
        dHead.next=head;
        //按步长循环分块归并
        for(int step=1;step<len;step*=2){
            //每次归并完重新重新拆分
            ListNode pre=dHead;
            ListNode cur=dHead.next;
            //按步长迭代拆分归并

            while(cur!=null){
                //第一部分头
                ListNode h1=cur;
                //第二部分头  
                ListNode h2=split(h1,step);

                //剩余部分的头:迭代下次拆分
                cur=split(h2,step);

                //归并
                ListNode mergeHead=merge(h1,h2);

                //整个链表连接
                pre.next=mergeHead;
                while(pre.next!=null){
                    pre=pre.next;
                }
                pre.next=cur;
            }
        }

        return dHead.next;
    }

    //获取链表长度
    public int getLength(ListNode head){
        int len=0;
        while(head!=null){
            len++;
            head=head.next;
        }
        return len;
    }

    //拆分
    public ListNode split(ListNode head,int step){
        if(head==null){
            return null;
        }

        ListNode cur=head;
        for(int i=1;i<step;i++){
            if(cur.next!=null){
                cur=cur.next;
            } 
        }
        ListNode right=cur.next;
        cur.next=null;
        return right;
    }

    //归并操作
    public ListNode merge(ListNode l1,ListNode l2){
        ListNode dHead=new ListNode(-1);
        ListNode tmp=dHead;

        while(l1!=null&&l2!=null){
            if(l1.val<l2.val){
                tmp.next=l1;
                tmp=l1;
                l1=l1.next;
            }else{
                tmp.next=l2;
                tmp=l2;
                l2=l2.next;
            }
        }

        if(l1==null){
            tmp.next=l2;
        }
        if(l2==null){
            tmp.next=l1;
        }

        return dHead.next;
    }
}

复杂度

时间复杂度O(n log n):外层log n内层n
空间复杂度O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值