链表排序时间复杂度为(O(n log n) )

题目:

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

解题思路:

因为题目要求复杂度为O(nlogn),故可以考虑归并排序的思想。

归并排序的一般步骤为:

1)将待排序数组(链表)取中点并一分为二;

2)递归地对左半部分进行归并排序;

3)递归地对右半部分进行归并排序;

4)将两个半部分进行合并(merge),得到结果。

 

所以对应此题目,可以划分为三个小问题:

1)找到链表中点 (快慢指针思路,快指针一次走两步,慢指针一次走一步,快指针在链表末尾时,慢指针恰好在链表中点);

2)写出merge函数,即如何合并链表。 (见merge-two-sorted-lists 一题解析)

3)写出mergesort函数,实现上述步骤。

package leetcode;
public class Class_sortList {
	public static ListNode createList() {
		ListNode[] list = new ListNode[6];
		int[] arr = { 1, 3, 2, 5, 4, 6 };
		for (int i = 0; i < 6; i++) {
			list[i] = new ListNode(arr[i]);
		}
		for (int i = 0; i < 5; i++) {
			list[i].next = list[i + 1];
		}
		list[5].next = null;
		return list[0];
	}
	/*
	 * 解题思路: 定义一快一慢的两个指针,快指针指向第二个节点,慢指针指向第一个节点;
	 * 慢指针一次走一步,快指针一次走两步,当快指针到达链表的尾部时,此时慢指针就是要找的中间节点。
	 */
	public static ListNode getMiddleListNode(ListNode pHead) {
		if (pHead == null) {
			return null;
		}
		ListNode pSlow = pHead;
		ListNode pFast = pSlow.next;
		while (pFast != null && pFast.next != null) {
			pSlow = pSlow.next;
			pFast = pFast.next.next;
		}
		return pSlow;
	}
	public static ListNode mergerLists(ListNode l1, ListNode l2) {
		if (l1 == null) {
			return l2;
		}
		if (l2 == null) {
			return l1;
		}
		ListNode head = new ListNode(0);
		ListNode p = head;
		while (l1 != null && l2 != null) {
			if (l1.val >= l2.val) {
				p.next = l2;
				l2 = l2.next;
			} else {
				p.next = l1;
				l1 = l1.next;
			}
			p = p.next;
		}
		if (l1 != null) {
			p.next = l1;
		}
		if (l2 != null) {
			p.next = l2;
		}
		return head.next;
	}
	public static ListNode sortList(ListNode head) {
		if (head == null || head.next == null) {
			return head;
		}
		ListNode mid = getMiddleListNode(head);
		ListNode right = sortList(mid.next);
		mid.next = null;
		ListNode left = sortList(head);
		return mergerLists(left, right);
	}

	public static void print(ListNode head) {
		ListNode p = head;
		while (p != null) {
			System.out.print(p.val + " ");
			p = p.next;
		}
	}
	public static void main(String[] args) {
		ListNode head = createList();
		ListNode res = sortList(head);
		print(res);
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值