Leetcode148.排序链表

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

在常见排序算法中,只有归并排序和堆排序时间复杂度为O(nlgn)。在本题中,很明显是用归并排序。而在数组的归并排序中,是先将数组分半,分递归归并排序后,再合并的。在链表中,需要找到中点,将链表分为两段。

在之前的一题回文链表中,用到了findMiddle函数,但是在这里却行不通了。对于节点数为偶数的链表,会陷入死循环。为此,findMiddle中的快指针应指向第一个节点的后继,代码如下:

ListNode* findMiddle(ListNode* head)
{
    if(head == nullptr || head->next == nullptr)
        return head;
    ListNode* fast = head->next, *slow = head;
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
    }
    return slow;
}

之后进行归并排序就很简单了,不要忘记将两段链表中间给断开。

ListNode* sortList(ListNode* head)
{
	if (head == nullptr || head->next == nullptr)
		return head;
	//将链表分为first和second两段
	ListNode* first = head;
	ListNode* middle = findMiddle(head);
	ListNode* second = middle->next;
	middle->next = nullptr;
	first = sortList(first);
	second = sortList(second);
	//归并,即合并两个有序链表
	return mergeTwoLists(first, second);
}

猜你喜欢

转载自blog.csdn.net/hlk09/article/details/81188406
今日推荐