zoukankan      html  css  js  c++  java
  • LeetCode 148 排序链表

    题目:

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

    示例 1:

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

    示例 2:

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

    解题思路:

    可达到O(nlogn)的排序我们知道有三种,堆排、快排、二路归并。  这里由于是链表,堆排和归并都不太容易操作。所以这里我们用二路归并算法。

    二路归并有递归的和非递归的,这里单链表,用非递归较为简单。因为递归要比较两个区间的大小,这里需要用到双指针。

    代码:

     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)
    13             return NULL;
    14         ListNode *p = head;
    15         int len = 0;
    16         while(p) {
    17             len++;
    18             p = p->next;
    19         }
    20 
    21         ListNode *temp = new ListNode(0);
    22         temp->next = head;
    23 
    24         int interval;
    25         for(interval = 1; interval <= len; interval *= 2) { //从下往上归并
    26             
    27             ListNode *pre = temp;
    28             ListNode *first = temp->next;
    29             ListNode *second = temp->next;
    30 
    31             while(first && second) {
    32                 int i = 0;
    33                 while(i < interval && second) {
    34                     second = second->next;
    35                     i++;
    36                 }
    37                 int fvisit = 0;
    38                 int svisit = 0;
    39                 while(fvisit < interval && svisit < interval && first && second) {
    40                     if(first->val < second->val) { //前指针较小,则把前指针装入放在前头
    41                         pre->next = first;
    42                         pre = first;
    43                         first = first->next;
    44                         fvisit++;
    45                     }
    46                     else {
    47                         pre->next = second;
    48                         pre = second;
    49                         second = second->next;
    50                         svisit++;
    51                     }
    52                 }
    53                 while(fvisit < interval && first) {//剩下的较大的就依次接上就好
    54                     pre->next = first;
    55                     pre = first;
    56                     first = first->next;
    57                     fvisit++;
    58                 }
    59                 while(svisit < interval && second) {
    60                     pre->next = second;
    61                     pre = second;
    62                     second = second->next;
    63                     svisit++;
    64                 }
    65                 pre->next = second; //往后继续直到第一次排序结束
    66                 first = second;
    67             }
    68         }
    69         ListNode *ans = temp->next;
    70         delete temp;
    71         return ans;
    72     }
    73 };
  • 相关阅读:
    Codevs 2296 仪仗队 2008年省队选拔赛山东
    Codevs 1535 封锁阳光大学
    Codevs 1069 关押罪犯 2010年NOIP全国联赛提高组
    Codevs 1218 疫情控制 2012年NOIP全国联赛提高组
    Codevs 1684 垃圾陷阱
    洛谷 P1108 低价购买
    Vijos P1325桐桐的糖果计划
    Codevs 3289 花匠 2013年NOIP全国联赛提高组
    Codevs 2611 观光旅游(floyed最小环)
    C语言基础之彩色版C语言(内含linux)
  • 原文地址:https://www.cnblogs.com/moxiangfeng/p/10728639.html
Copyright © 2011-2022 走看看