zoukankan      html  css  js  c++  java
  • 143. Reorder List

    本周对链表操作进行了巩固

    题目:

    Given a singly linked list LL0→L1→…→Ln-1→Ln,
    reorder it to: L0→LnL1→Ln-1→L2→Ln-2→…

    You must do this in-place without altering the nodes' values.

    For example,
    Given {1,2,3,4}, reorder it to {1,4,2,3}.

    题解:

      这道题虽然看上去很复杂,但经过分析,可知实质上这道题就是将原链表对半分开,然后将后半部分逆置,合并插入到前半部分中。

      对于链表的划分,是通过快慢指针来实现的:一开始将两个指针同时指向链表的头部,然后其中一个指针每次循环走1步,慢指针每次循环走2步,直到快指针触到了链表的末端。最终慢指针对应的就是链表的后半部分。在该题的情况下,只需要对满指针的下一个以及随后的节点进行逆置即可。

      得到逆置后的后半部分以及前半部分之后,先将链表从快慢指针之间截断,然后进行循环遍历。在本题中,后半部分的节点个数,小于或等于前半部分,循环结束的标志也就是后半部分是否已经到达末尾。在插入的操作中,只需要注意变量值的交换(两个节点的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* reverseList(ListNode* head)
    12     {
    13         //对链表进行逆置
    14         if(head==NULL) return NULL;
    15         ListNode* tail = head;
    16         while(tail->next!=NULL)
    17             tail = tail->next;
    18         
    19         ListNode* curr = head;
    20         while(curr!=tail)
    21         {
    22             ListNode* temp = curr->next;
    23             curr->next = tail->next;
    24             tail->next = curr;
    25             curr = temp;
    26         }
    27         return tail;
    28     }
    29     
    30     void reorderList(ListNode* head) 
    31     {
    32         if(head==NULL) return;
    33         
    34         //通过快慢指针来找到链表的中点
    35         ListNode *fast = head;
    36         ListNode *slow = head;
    37         while(fast->next!=NULL&&fast->next->next!=NULL)
    38         {
    39             fast = fast->next->next;
    40             slow = slow->next;
    41         }
    42         //链表中如果只有一个或两个节点,无需进行下面的操作了,直接返回
    43         if(fast==slow) return;
    44         
    45         ListNode* slow_rev = reverseList(slow->next);
    46         //将链表从中间断开
    47         slow->next = NULL;
    48         ListNode* curr = head;
    49         //合并两个链表
    50         while(slow_rev)//后半段的链表节点数比前半段的少
    51         {
    52             ListNode* temp1 = slow_rev->next;
    53             ListNode* temp2 = curr->next;
    54             curr->next = slow_rev;
    55             slow_rev->next = temp2;
    56             slow_rev = temp1;
    57             curr = temp2;
    58         }
    59         
    60     }
    61 };
  • 相关阅读:
    关于基础排序算法的思考--插入排序
    关于购物车的多层复选全选
    随便写写
    第一篇小博文
    C# 遍历目录下所有文件方法
    C#驱动MongoDB官方中查询条件Query用法
    mongodb 修改远程连接
    Python 爬虫练习低调163疫情数据辽宁地图
    jquery easyui datagrid drop事件执行顺序
    https request报错 ServicePointManager.SecurityProtocol 搞定
  • 原文地址:https://www.cnblogs.com/MT-ComputerVision/p/6539480.html
Copyright © 2011-2022 走看看