[C++]LeetCode: 125 Sort List (归并排序链表)

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

思路:题目要求我们使用常数空间复杂度,时间复杂度为O(nlog(n)). 满足这个时间复杂度的有快速排序,归并排序,堆排序。插入排序时间复杂度为O(n^2). 双向链表用快排比较合适,堆排序也可用于链表,单项链表适合于归并排序。我们就用归并排序的思想来完成链表的排序。

首先是用快慢双指针找到链表中间的位置,然后分成前后端分别递归的归并排序,最后合并。

Attention:

1. 快慢指针找中间节点的方法,是常用方法,要熟练使用。

//将链表分成前后两部分 双指针找到中间节点
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast->next != NULL && fast->next->next != NULL)
        {
            slow = slow->next;
            fast = fast->next->next;
        }

2. 链表的数据结构是如何实现归并的方法的。定义一个合并后的链表,然后把合适的节点放进去。思想和数组是一样的,只是链表操作不一样。

复杂度:如果这里我们考虑递归的栈空间的话,空间复杂度是O(lg(n))

AC Code:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *sortList(ListNode *head) {
        if(head == NULL || head->next == NULL) return head;
        //将链表分成前后两部分 双指针找到中间节点
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast->next != NULL && fast->next->next != NULL)
        {
            slow = slow->next;
            fast = fast->next->next;
        }
        ListNode* head2 = slow->next;
        slow->next = NULL;
        ListNode* head1 = head;
        head1 = sortList(head1);   //前半段归并排序
        head2 = sortList(head2);   //后半段归并排序
        return merge(head1, head2);
    }

private:
    ListNode* merge(ListNode* h1, ListNode* h2)
    {
        ListNode* dummyhead = new ListNode(0);
        ListNode* mlist = dummyhead;

        while(h1 != NULL && h2 != NULL)
        {
            if(h1->val <= h2->val)
            {
                mlist->next = h1;
                h1 = h1->next;
            }
            else
            {
                mlist->next = h2;
                h2 = h2->next;
            }
            mlist = mlist->next;
        }
        if(h1 != NULL)
        {
            mlist->next = h1;
        }
        if(h2 != NULL)
        {
            mlist->next = h2;
        }
        return dummyhead->next;
    }
};

我们也可以不使用递归的方法,自底向上的非递归版本的归并排序,空间复杂度就是常数了。可以看下这篇博文:sort list.

排序是面试中很常见和基础的一个主题,我们需要对各种常见的排序算法要熟悉。尤其是算法的原理,很多题目虽然没有直接考察排序的实现,但是会用到其中的思想,比如经典的topK问题,用到了快排的原理。这篇文章中有提到,可以看看:Median of Two Sorted Arrays.所以我们应该要更加注重排序算法的原理。

时间: 2024-11-08 19:21:49

[C++]LeetCode: 125 Sort List (归并排序链表)的相关文章

leetcode——Insertion Sort List 对链表进行插入排序(AC)

Sort a linked list using insertion sort. class Solution { public: ListNode *insertionSortList(ListNode *head) { if(head == NULL || head->next == NULL) return head; ListNode *result; result->val = INT_MIN; result->next = NULL; ListNode *cur=head,*

【LeetCode】 sort list 单链表的归并排序

题目:Sort a linked list in O(n log n) time using constant space complexity. 思路:要求时间复杂度O(nlogn) 知识点:归并排序,链表找到中点的方法 存在的缺点:边界条件多考虑!!! /** * LeetCode Sort List Sort a linked list in O(n log n) time using constant space complexity. * 题目:将一个单链表进行排序,时间复杂度要求为o

Leetcode 148. Sort List 归并排序 in Java

148. Sort List Total Accepted: 81218 Total Submissions: 309907 Difficulty: Medium Sort a linked list in O(n log n) time using constant space complexity. /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; *

LeetCode OJ - Sort List

题目: Sort a linked list in O(n log n) time using constant space complexity. 解题思路: 复杂度为O(n* logn) 的排序算法有:快速排序.堆排序.归并排序.对于链表这种数据结构,使用归并排序比较靠谱.递归代码如下: 代码: /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNod

leetcode linkedList sort

链表排序:算法-归并排序 public class LinkedSort { private static class ListNode { int val; ListNode next; ListNode(int x) { val = x; next = null; } } private ListNode mergeList(ListNode head1,ListNode head2){ if(head1==null){ return head2; }else if(head2==null)

Sort List &amp;&amp; Insertion Sort List (链表排序总结)

Sort List Sort a linked list in O(n log n) time using constant space complexity. Have you been asked this question in an interview?                   Yes               说明:归并排序: 时间 O(nlogn),空间 O(1). 每次将链表一分为二, 然后再合并.快排(用两个指针) /** * Definition for sing

[leetcode]Insertion Sort List @ Python

原题地址:http://oj.leetcode.com/problems/insertion-sort-list/ 题意:对链表进行插入排序. 解题思路:首先来对插入排序有一个直观的认识,来自维基百科. 代码循环部分图示: 代码: class Solution: # @param head, a ListNode # @return a ListNode def insertionSortList(self, head): if not head: return head dummy = Lis

【Leetcode解题报告】单链表排序问题

Leetcode 21 Merge Two Sorted Lists 问题描述 Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. 分析与解法 这个问题没有什么多的解释,直接合并:看代码: 1 /** 2 * Definition for singly-linked

LeetCode :: Insertion Sort List [详细分析]

Sort a linked list using insertion sort. 仍然是一个非常简洁的题目,让我们用插入排序给链表排序:这里说到插入排序,可以来回顾一下, 最基本的入门排序算法,就是插入排序了:时间复杂度为n^2,最基本的插入排序是基于数组实现的,下面给出基于数组实现的插入排序,来体会一个插入排序的思想: 以下仅为数组实现,不是解题代码,没兴趣可以跳过. void insertionsort (int a[], int N) { for (int i = 1; i < N; i+