LeetCode题解(Week2):148. Sort List

原题目

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

中文大意

对一个链表进行排序,要求算法的时间复杂度是O(n log n),空间复杂度是常数


题解

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode *dummy = new ListNode(-1);
        ListNode *ans = dummy;

        while(l1!=NULL && l2!=NULL)
        {
            if(l1->val > l2->val)
            {
                dummy->next = l2;
                l2 = l2->next;
            }
            else
            {
                dummy->next = l1;
                l1 = l1->next;
            }
            dummy = dummy->next;
        }
        while(l1!=NULL)
        {
            dummy->next = l1;
            l1 = l1->next;
            dummy = dummy->next;
        }
        while(l2!=NULL)
        {
            dummy->next = l2;
            l2 = l2->next;
            dummy = dummy->next;
        }
        ListNode *temp = ans;

        ans = ans->next;

        delete temp;
        return ans;
    }

    ListNode* sortList(ListNode* head) 
    {
        if(head == NULL) return NULL;
        if(head->next ==NULL) return head;

        //利用快慢指针来定位链表的中点
        ListNode *tail = head;
        ListNode *mid = head;
        while(tail->next!=NULL && tail->next->next!=NULL)
        {
            tail = tail->next->next;
            mid = mid->next;
        }

        tail = mid;
        mid = mid->next;
        tail->next = NULL; //将链表从中间断开
        //分治求解问题
        ListNode* l1 = sortList(mid);
        ListNode* l2 = sortList(head);

        //将两个排序好的子链表合并
        return mergeTwoLists(l1,l2);
    }
};

思路

  • 本题的要求的是在O(n log n)下解决问题,因此,在常用的排序算法(快速排序与归并排序)中, 快速排序法的最坏情况是O(N^2),不适用与本题,而且,从数据结构的本身来说,对于链表最优的排序方法基本上就是归并排序,因为不需要像数组一样,额外分配空间。自然地,用归并来实现链表排序,算法空间复杂度也是O(1)的,符合本题目要求
  • 得出这样的结论以后,就可以使用常规的归并排序思路来解这道题,典型的分治法。首先通过快慢指针来找到链表的中点,然后将链表断开,一分为二,变成两个新的链表,再对子链表进行划分。最后再将两个链表用上一篇文章中提到的方法合并在一起
  • 值得注意的是这里的递归边界条件:当链表中头为空或者链表中只有一个元素,就不再执行递归

心得体会

经过这道题才发现原来在Leetcode中可以直接通过算法的入口函数实现递归,比如这道题的入口是sortList,可以直接用sortList作为递归函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值