leetcode 148. 排序链表-java题解

题目所属分类

原题链接

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

代码案例:在这里插入图片描述
输入:head = [4,2,1,3]
输出:[1,2,3,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 n =  0 ;
        for(ListNode p = head ; p != null ; p = p.next ) n ++ ;
       ListNode dummy = new ListNode(-1);
            dummy.next = head ;
        for(int i = 1 ; i < n ; i *= 2){//第一行
          ListNode cur = dummy;
            for(int j = 1 ; j + i <= n ; j += i*2){
                ListNode p = cur.next , q = p ;
                for(int k = 0 ; k < i ;k++)q=q.next ;
                //接下来是归并
                int l = 0 , r = 0 ;
                while(l < i && r < i && p != null && q !=null){
                    if(p.val <= q.val){
                         cur.next = p ;
                        p = p.next;
                        l++;
                    }else{
                        cur.next = q ;
                        q = q.next ;
                        r++ ;
                    }
                   cur = cur.next;
                }
                while(l < i && p != null){
                    cur = cur.next = p ;
                        p = p.next;
                        l++;
                }
                while( r < i && q != null){
                     cur = cur.next = q ;
                        q = q.next ;
                        r++ ;
                }
                cur.next = q ;//更新每一个cur 
            }
            
        }
        return dummy.next;
    }
}

在这里插入图片描述

通过快慢指针的方式找到当前链表的中点,将左边部分和右边部分分开形成两个链表,并分别进行排序,注意的是左边部分的尾指针需要指向 null,最后排序后的两个链表进行合并,并进行返回

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    static ListNode merge(ListNode left, ListNode right)
    {
        ListNode dummy = new ListNode(-1);
        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;
        }
        if(left != null) cur.next = left;
        else cur.next = right;

        return dummy.next; 
    }
    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;
        }

        fast = slow.next;
        slow.next = null;

        ListNode left = sortList(head);
        ListNode right = sortList(fast);

        return merge(left, right);
    }
}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依嘫_吃代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值