LeetCode | Sort List

本文介绍了一种在O(n log n)时间复杂度和常量空间复杂度下对单链表进行排序的方法。通过使用归并排序算法,并利用快慢指针技术实现链表的折半划分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题描述:https://oj.leetcode.com/problems/sort-list/

     Sort a linked list in O(n log n) time using constant space complexity.


解题思路:

     题目要求 O(n*lgn)的时间复杂度和常量的空间复杂度,来实现单链表的排序。

     对于O(n*lgn)时间复杂度的排序算法,我们很容易就能想到快速排序、归并排序和堆排序。其中,快速排序要求能在常数时间内交换两个元素,这个单链表是无法实现的,所以排除之。堆排序需要O(n)的空间复杂度来建堆,所以也排除之。于是,我采用归并排序来实现。

     单链表的归并排序,关键点就是链表的折半划分与合并。怎样来实现链表的折半划分呢?我们可以通过快慢指针法来实现,设定一个慢指针(步长为1)和快指针(步长为2),然后同步扫描链表,当快指针扫描到链表尾部时,由于快指针的步长是慢指针的2倍,所以慢指针所停在的位置就是链表的二分点。至于两个有序链表的合并,无非就是依次扫描对比,然后按序添加到新链表中。


代码实现:

public class Solution {

	class ListNode {
		int val;
		ListNode next;

		ListNode(int x) {
			val = x;
			next = null;
		}
	}

	public ListNode sortList(ListNode head) {
		ListNode head1, head2;
		if (head == null || head.next == null)
			return head;
		ListNode slow = head, fast = head;
		while (fast != null && fast.next != null && fast.next.next != null) {
			slow = slow.next;
			fast = fast.next.next;
		}
		head1 = head;
		head2 = slow.next;
		slow.next = null;
		head1 = sortList(head1);
		head2 = sortList(head2);
		return merge(head1, head2);
	}

	private ListNode merge(ListNode head1, ListNode head2) {
		if (head1 == null) {
			return head2;
		} else if (head2 == null) {
			return head1;
		}
		ListNode head, index;
		if (head1.val <= head2.val) {
			head = head1;
			head1 = head1.next;
		} else {
			head = head2;
			head2 = head2.next;
		}
		index = head;
		while (head1 != null && head2 != null) {
			if (head1.val <= head2.val) {
				index.next = head1;
				head1 = head1.next;
			} else {
				index.next = head2;
				head2 = head2.next;
			}
			index = index.next;
		}
		if (head1 != null) {
			index.next = head1;
		}
		if (head2 != null) {
			index.next = head2;
		}
		return head;
	}

}
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值