链表TOP难度——排序链表

https://leetcode.cn/problems/sort-list/?envType=study-plan-v2&envId=top-interview-150
在这里插入图片描述采用分治思想解决这题,每次合并长度为1\2\4…的链表,合并思想和合并有序链表一致,单独写成一个函数即可。
合并思路如下:

while(分治长度)
	定义一个头节点节点方便链表连接
	while(每两个链表进行合并)
		进行遍历取到左边一个链表
		链表末尾指空
		进行遍历取到右边一个链表
		链表末尾指空
		两个链表合并
		头节点连接到这个链表
		头节点指向这个链表的尾部

在这里插入图片描述

具体代码如下:

class Solution {
    public ListNode sortList(ListNode head) {
        int length = 0;
        //先计算链表的长度
        ListNode listNode = head;
        while(listNode!=null){
            length++;
            listNode = listNode.next;
        }
        ListNode dummyHead = new ListNode(0,head);
        for(int subLength=1;subLength<length;subLength*=2){
            //从长度为1的链表开始合并
            //分别求出两个合并节;
            //排序后的链表需要接上前面的
            ListNode pre = dummyHead;
            ListNode curr = dummyHead.next;
            while(curr!=null){
                //这里的做法非常复杂
               ListNode head1 = curr;
                for (int i = 1; i < subLength && curr.next != null; i++)
                    curr = curr.next;
                //先把这个链表的下一个节点记下来,然后直接让最后一个节点指空
                //让当前链表独立出来
                ListNode head2 = curr.next;
                curr.next = null;
                curr = head2;
                //可能由于长度的问题导致了第二个节点找不到了直接判空
                for (int i = 1; i < subLength && curr != null && curr.next != null; i++)
                    curr = curr.next;
                ListNode next = null;
                if(curr!=null){
                    next = curr.next;
                    curr.next = null;
                }
                ListNode merged = merge(head1,head2);
                pre.next = merged;
                //将这个前置节点放到排序后的链表的最后一个
                while(pre.next!=null){
                    pre = pre.next;
                }
                //节点后移动,排序后的链表连接全靠pre
                curr= next;
            }         
        }
        return dummyHead.next;
    }
    public ListNode merge(ListNode head1, ListNode head2) {
        ListNode dummyHead = new ListNode(0);
        ListNode temp = dummyHead, temp1 = head1, temp2 = head2;
        while (temp1 != null && temp2 != null) {
            if (temp1.val <= temp2.val) {
                temp.next = temp1;
                temp1 = temp1.next;
            } else {
                temp.next = temp2;
                temp2 = temp2.next;
            }
            temp = temp.next;
        }
        if (temp1 != null) {
            temp.next = temp1;
        } else if (temp2 != null) {
            temp.next = temp2;
        }
        return dummyHead.next;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值