有意思的题目,正常思路是插入排序,时间复杂度过高,再考虑用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; }