给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
给定链表 1->2->3->4, 重新排列为 1->4->2->3.
示例 2:
给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.
思路分析:先扫描一遍链表,将链表的节点地址序列保存到容器中,然后根据对称的规律重排链表即可。(L0→Ln下标关于链表中心对称,L1→Ln-1下标关于链表中心对称…)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void reorderList(ListNode* head) {
vector<ListNode*> myVec;//保存链表序列
//ptr用于扫描链表, endPtr用于记录重排后的尾端
ListNode *ptr = head, *endPtr = head;
//扫描链表
while (ptr != NULL) {
myVec.push_back(ptr);
ptr = ptr->next;
}
int vecSize = myVec.size();
if (vecSize <= 2) {
return;
}
//首先放置原来的头、尾
endPtr = head;
endPtr->next = myVec[vecSize - 1];
endPtr = endPtr->next;
int nowIndex = 1;//即将访问的下一个节点
int endIndex = vecSize / 2;//对称关系,截止下标
if (vecSize % 2 == 0){//如果链表节点是偶数个,最后需要减少一对,因为后面还有一对
endIndex -= 1;
}
//循环重排(对称性)
while (nowIndex < endIndex) {
endPtr->next = myVec[nowIndex];
endPtr = endPtr->next;
endPtr->next = myVec[vecSize - nowIndex - 1];
endPtr = endPtr->next;
++nowIndex;
}
//后面还有一个(如果是偶数那就还有一对)
endPtr->next = myVec[nowIndex++];
endPtr = endPtr->next;
if (vecSize % 2 == 0) {
endPtr->next = myVec[nowIndex++];
endPtr = endPtr->next;
}
//最后需要封口
endPtr->next = NULL;
}
};