LeetCode Reorder List

来源:互联网 发布:win10没有软件 编辑:程序博客网 时间:2024/05/16 17:24

题目大意:给一个单链表:L0->L1->L2->L3-> ... ->Ln-1->Ln,将其重排为:L0->Ln->L1->Ln-1->L2->Ln-2->...

要求:1、就地重排;2、改变指针的指向,而不是直接修改结点的值。


分析:直接的想法就是依次截取最后的结点,插入到要求的位置。但是,考察每个插入的位置需要遍历一遍单链表,每次找到最后一个结点也需要遍历一遍单链表,程序结构为两个嵌套的循环,时间复杂度是O(n*n)的。提交后超时。

改进的算法如下:

先遍历一遍链表,统计链表长度,根据长度,截取链表的后半段;然后将后半段倒置(头插法);再将前半段和后半段两个单链表交替合并。算法的时间复杂度应该是O(n),AC。算法图解如下:


代码如下:

#include<iostream>using namespace std;struct ListNode {    int val;    ListNode *next;    ListNode(int x) : val(x), next(NULL) {} };class Solution {public:    void reorderList(ListNode *head) {ListNode *p,*q,*r,*h1,*h2;int len=0,len1,len2; if(!head || !head->next || !head->next->next)return ;p=head;while(p){//获取整个链表长度 ++len;p=p->next;}if(len%2==0){len1=len/2+1;len2=len/2-1;}else{len1=len/2+1;len2=len/2;}q=head;h2=head->next;for(int i=1;i<len1;++i){q=q->next;h2=h2->next;}q->next=NULL;//截断原始链表p=h2;//头插法,将后半段链表倒置 q=p->next;while(q){p->next=q->next;q->next=h2;h2=q;q=p->next;}//交替合并两段链表h1=head;p=h1->next;q=h2->next;while(q){h1->next=h2;h2->next=p;h1=p;h2=q;p=h1->next;q=h2->next;}h1->next=h2;h2->next=p;    }};


0 0
原创粉丝点击