leetcode148.排序链表

发布于:2024-12-18 ⋅ 阅读:(112) ⋅ 点赞:(0)

标签:归并排序,合并链表

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

示例 1:

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

示例 2:

输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]

示例 3:

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

提示:链表中节点的数目在范围 [0, 5 * 104] 内

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

思路:话不多说,直接上进阶解题思路,因为面试考官要的就是手撕进阶答法(百度是这样的),排序O(nlogn)直接想到归并排序,两两一组不断合并,直到合并到长度为链表长度。注意一组的长度是2倍递增的,例如:1 1->2    2 2->4....用到了leetcode21.合并两个有序列表-CSDN博客知识。

public ListNode sortList(ListNode head) {
        // 0/1个节点
        if(head==null||head.next==null)
            return head;
        // 统计节点长度
        int length=0;
        ListNode count=head;
        while(count!=null) {
            length++;
            count=count.next;
        }
        // 两两一组合并 为每一组的开头和结尾都设置一个指针
        ListNode lis1_start=head;
        ListNode lis1_stop=head;
        ListNode lis2_start=head;
        ListNode lis2_stop=head;
        ListNode cur=head;// cur往下找新的组
        ListNode node=new ListNode(0,head); // node作为虚拟头节点,后面是连接排好的组
        ListNode end=node;// 和node搭配 表示当前连接好的组的结尾节点
        // 一直合并到组长度为length
        for(int sum=1;sum<length;sum*=2){
            lis1_start=node.next;
            lis1_stop=node.next;
            lis2_start=node.next;
            lis2_stop=node.next;
            cur=node.next;
            end=node;
            //执行 n/sum次
            while(cur!=null){
                lis1_start=cur;
                lis1_stop=cur;
                for(int i=1;i<sum&&lis1_stop!=null;i++){
                    lis1_stop=lis1_stop.next;
                }

                if(lis1_stop!=null)
                    lis2_start=lis1_stop.next;
                else 
                    lis2_start=null;
                lis2_stop=lis2_start;

                if(lis1_stop!=null)
                    lis1_stop.next=null;
                for(int i=1;i<sum&&lis2_stop!=null;i++){
                    lis2_stop=lis2_stop.next;
                }
                if(lis2_stop!=null){
                    cur=lis2_stop.next;
                    lis2_stop.next=null;
                }
                else 
                    cur=null;
                // sum*2
                ListNode dummy=mergeTwoLists(lis1_start,lis2_start);
                end.next=dummy;
                while(end.next!=null)
                    end=end.next;
            }
        }
        return node.next;
    }

    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode ret=new ListNode(0);
        ListNode head=ret;
        while(list1!=null||list2!=null){
            if(list1==null||list2!=null&&list2.val<=list1.val){
                ret.next =list2;
                list2=list2.next;
            }
            else if(list2==null||list1!=null&&list1.val<=list2.val){
                ret.next =list1;
                list1=list1.next;
            }
            ret=ret.next;
        }
        return head.next;
    }


网站公告

今日签到

点亮在社区的每一天
去签到