力扣——排序链表

发布于:2025-03-15 ⋅ 阅读:(16) ⋅ 点赞:(0)

题目链接:

链接

题目描述:

在这里插入图片描述

思路:

归并排序

递归实现

用双指针找到中间点,然后把链表分成两个部分,不断进行这个操作,直到next或当前节点为null
返回当前节点,回到“上一步”

在“上一步”里,把返回的节点接受为自己的左右两段部分的头结点
然后根据大小进行合并

相邻节点直接合并

省去拆分的操作,直接合并相邻的节点
在这里插入图片描述

实现代码:

class Solution {
    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){
            fast = fast.next.next;
            slow = slow.next;
        }
        ListNode tmp = slow.next;
        slow.next = null;
        //再分割
        ListNode left = sortList(head);
        ListNode right = sortList(tmp);
        //虚拟头
        ListNode dummy = new ListNode(0);
        ListNode cur = dummy;
        //合并
        while(left != null && right != null){
            if(left.val < right.val){
                cur.next = left;
                left = left.next;
            } else{
                cur.next = right;
                right = right.next;                
            }
            cur = cur.next;
        }
        cur.next = left != null ? left : right;
        return dummy.next;
    }
}
class Solution {
    public ListNode sortList(ListNode head) {
        if(head == null){
            return head;
        }
        int length = 0;
        ListNode node = head;
        while(node != null){
            length++;
            node = node.next;
        }
        ListNode dummy = new ListNode(0,head);
        for(int sublength = 1; sublength < length; sublength = sublength *2){
            ListNode pre = dummy, cur = dummy.next;
            while(cur != null){
                //找到第1段
                ListNode head1 = cur;
                for(int i = 1; i < sublength && cur.next != null; i++){
                    cur = cur.next;
                }
                ListNode head2 = cur.next;
                cur.next = null;
                //找到第2段
                cur = head2;
                for(int i = 1; i < sublength && cur != null && cur.next != null ; i++){
                    cur = cur.next;
                }
                //找到剩下的,下一次while就是合并剩下的里面前两段
                ListNode next = null;
                if(cur != null){
                    next = cur.next;
                    cur.next = null;
                }
                //合并
                ListNode merged = merge(head1,head2);
                pre.next = merged;
                while(pre.next != null){
                    pre = pre.next;
                }
                cur = next;
            }
        }
        return dummy.next;
    }

    public ListNode merge(ListNode head1, ListNode head2){
        ListNode dummy = new ListNode(0);
        ListNode tmp = dummy, tmp1 = head1, tmp2 = head2;
        while(tmp1 != null && tmp2 != null){
            if(tmp1.val <= tmp2.val){
                tmp.next = tmp1;
                tmp1 = tmp1.next;
            }else{
                tmp.next = tmp2;
                tmp2 = tmp2.next;
            }
            tmp = tmp.next;
        }
        tmp.next = tmp1 != null ? tmp1 : tmp2;
        return dummy.next;
    }
}

网站公告

今日签到

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