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 };

 

转载于:https://www.cnblogs.com/MT-ComputerVision/p/6539480.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值