LeetCode HOT 100 —— 148.排序链表

题目

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
在这里插入图片描述
在这里插入图片描述

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

思路

题目要求时间空间复杂度分别为O(nlogn)和O(1),根据时间复杂度不难想到二分法,从而想到归并排序

通过递归实现链表归并排序,主要有两个过程:

  • 分割过程:找到当前链表中点,断开,可以采用快慢指针法,奇数个节点找到中点,偶数个节点找到中心左边的节点
  • 合并过程:将两个排序链表合并,转化成一个排序链表,使用双指针法合并,分别比较两个指针处节点值大小,按从小到大的顺序插入链表

在这里插入图片描述
java代码如下:

class Solution{//先分,再排序,最后合并
	public ListNode sortList(ListNode head){
		if (head == null || head.next == null)
			return head;
		
		//快慢指针找链表中点
		ListNode slow = head;
		ListNode fast = head.next;//这里fast要后移一位,因为如果是偶数位,我们找的是中心点的左边一个节点,因为这样方便判断边界,即slow即为上个区间的最后一个节点,如果不后移找到的就是中心点右边的节点,不方便划分区间,自己画个图走一遍就知道了
		while (fast != null && fast.next != null) {
			slow = slow.next;
			fast = fast.next.next;
		} 
		ListNode tmp = slow.next;//记录下个区间的起始边界位置
		slow.next = null;//断开链表,分成两个区间链表
		ListNode left = sortList(head);//排序左区间链表
		ListNode right = sortList(tmp);//排序右区间链表
		ListNode dummy = new ListNode(0);//创建虚拟头结点,用于最后返回结果
		ListNode h = dummy;//移动指针,用于添加节点
		
		//合并两个有序链表
		while (left != null && right != null) {//只要两个链表都不为空
			if (left.val < right.val) {//分别比较两个链表的节点值大小并加入	
				h.next = left;//将小的节点加入结果链表
				left = left.next;//同时指针后移
			} else {
				h.next = right;
				right = right.next;
			}
			h = h.next;//加入完节点后,结果链表中的指针后移,方便继续添加后续节点
		}
		h.next = (left != null ? left : right);//如果有链表没有加入完毕,则直接加入剩下非空的节点
		return dummy.next;//返回结果链表
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

HDU-五七小卡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值