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 };
  • 相关阅读:
    在日期选择轮中选择的时间转换成年龄
    字符串转换成NSDate类型的 为nil解决方法
    字符串与数组互转
    使用ASI传递post表单..参数是数组
    java synchronized的四种用法
    java 多线程实现的四种方式
    java 高性能Server —— Reactor模型单线程版
    java nio socket使用示例
    java.nio.Buffer 中的 flip()方法
    java NIO 详解
  • 原文地址:https://www.cnblogs.com/moxiangfeng/p/10728639.html
Copyright © 2011-2022 走看看