LeetCode 148. 排序链表(Sort List)

题目描述

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

示例 1:

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

示例 2:

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

解题思路

本题其实是让用归并排序的思想对链表进行排序,分为两个阶段:首先将整个链表分为两部分,一般是从中间切开,对两部分分别进行排序;然后将两个排序好的链表合并成一个链表。下面分别对两步进行分析:

  1. 将链表分为两部分时,要首先找到中间节点,考虑用快慢指针的方法,快指针每次走两步,慢指针每次走一步,这样当快指针无路可走即下两步出现空指针时,慢指针正好处于链表中间节点。然后从慢指针后把整个链表切成两半,两部分再分别进行递归排序
  2. 将两个排序链表合并时,首先初始化一个伪头节点,用其next指针指向新链表的头节点。从两个排序链表的头节点开始比较,每次将值较小的节点拼接到新链表后,若遇到其中一个节点为空则将另一个链表拼接到新链表后,这样遍历到两个链表末尾,最后返回伪头节点的next指针

代码

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* sortList(ListNode* head) {
12         if(head == NULL || head->next == NULL)
13             return head;
14         ListNode *quick = head, *slow = head;
15         //快慢指针找到中间节点
16         while(quick->next && quick->next->next){
17             quick = quick->next->next;
18             slow = slow->next;
19         }
20         quick = slow;
21         slow = slow->next;
22         quick->next = NULL;
23         ListNode *first = sortList(head);
24         ListNode *second = sortList(slow);
25         return mergeList(first, second);
26     }
27     ListNode* mergeList(ListNode* first, ListNode* second){
28         ListNode node(-1);
29         ListNode *p = &node;
30         while(first != NULL || second != NULL){
31             int val1 = first == NULL ? INT_MAX : first->val;
32             int val2 = second == NULL ? INT_MAX : second->val;
33             if(val1 < val2){
34                 p->next = first;
35                 first = first->next;
36             }
37             else{
38                 p->next = second;
39                 second = second->next;
40             }
41             p = p->next;
42         }
43         return node.next;
44     }
45 };

猜你喜欢

转载自www.cnblogs.com/wmx24/p/9329629.html