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 };
  • 相关阅读:
    jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解
    jQuery 源码解析(二十三) DOM操作模块 替换元素 详解
    jQuery 源码解析(二十二) DOM操作模块 复制元素 详解
    jQuery 源码分析(二十一) DOM操作模块 删除元素 详解
    jQuery 源码分析(二十) DOM操作模块 插入元素 详解
    jQuery 源码分析(十九) DOM遍历模块详解
    python 简单工厂模式
    python 爬虫-协程 采集博客园
    vue 自定义image组件
    微信小程序 image组件坑
  • 原文地址:https://www.cnblogs.com/MT-ComputerVision/p/6539480.html
Copyright © 2011-2022 走看看