
有意思的题目,正常思路是插入排序,时间复杂度过高,再考虑用vector存储,然后快排,这样实现简单,但是需要额外o(n)的空间复杂度。
考虑题目O(nlogn)时间复杂度,可以想到归并算法,这样空间复杂度就能降低,小于o(n),实际上是需要o(logn),但是已经接近于常数了。
参考常用的归并函数,写出如下代码。主要是拆分和合并的操作有些许不同,需要注意指针的问题。
#include<iostream>
#include <vector>
#include <set>
#include <functional>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <sstream>
#include <list>
#include <map>
#include <stack>
#include <algorithm>
#include<iomanip>
#define INT_MIN (-2147483647 - 1) /* minimum (signed) int value */
#define INT_MAX 2147483647 /* maximum (signed) int value */
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* findMid(ListNode* head)
{
if (head == nullptr)
return nullptr;
ListNode* slow = head;
ListNode* fast = head;
ListNode* result = head;
//当只有两个元素时,slow和fast指针都没动,重叠,需要单独处理
if (head->next->next == nullptr)
{
result = head->next;
head->next = nullptr;
return result;
}
while (fast != nullptr && fast->next != nullptr)
{
slow = slow->next;
fast = fast->next->next;
}
result = slow->next;
slow->next = nullptr;
return result;
}
ListNode* Merge(ListNode* p1, ListNode* p2)
{
ListNode* head = new ListNode(6);
ListNode* current = head;
while (p1 != nullptr && p2 != nullptr)
{
if (p1->val <= p2->val)
{
current->next = p1;
current = current->next;
p1 = p1->next;
}
else
{
current->next = p2;
current = current->next;
p2 = p2->next;
}
}
if (p1 != nullptr)
current->next = p1;
else if (p2 != nullptr)
current->next = p2;
current = head->next;
delete head;
head = nullptr;
return current;
}
ListNode* sortList(ListNode* head) {
if (head == nullptr)
return nullptr;
if (head->next == nullptr)
return head;
ListNode* mid = findMid(head);
head = sortList(head);
mid = sortList(mid);
head = Merge(head, mid);
return head;
}
int main(int argc, char** args)
{
ListNode* head = new ListNode(4);
head->next = new ListNode(2);
head->next->next = new ListNode(1);
head->next->next->next = new ListNode(3);
//head->next->next->next->next = new ListNode(5);
//head->next->next->next->next->next = new ListNode(6);
head = sortList(head);
ListNode* p = head;
while (p != nullptr)
{
cout << p->val << " ";
p = p->next;
}
cout << endl;
system("pause");
return 0;
}