题目描述
将给定的单链表L:L0→L1→…→Ln−1→Ln
重新排序为:L0→Ln→L1→Ln−1→L2→Ln−2→…
要求使用原地算法,不能改变节点内部的值,需要对实际的节点进行交换。
例如:
对于给定的单链表{10,20,30,40},将其重新排序为{10,40,20,30}.
解析:该题类似于回文子串的判断
/**
* 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) {
if(!head || !head->next) return;
ListNode* ret = head;
vector<int> arr;
while(ret!=NULL){
arr.push_back(ret->val);
ret = ret->next;
}
int n = arr.size();
int j = 0;
vector<int>res(n, 0);
for(int i=0;i<n;i=i+2){
res[i] = arr[j];
if(i+1 < n){
res[i+1] = arr[n-1-j];
}
j++;
}
ret = head;
for(int i=0;i<res.size();i++){
ret->val = res[i];
ret = ret->next;
}
return;
}
};
以下代码需要debug
/**
* 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) {
if(head==NULL || head->next==NULL)
return;
ListNode* ptr = head;
ListNode* end = NULL;
ListNode* tmp1=NULL,*tmp2=NULL;
ListNode* pHead=NULL;
int len = 0;
int pos = 0;
while(ptr!=NULL){
len++;
ptr = ptr->next;
}
end = head;
while(pos < len/2)//查找链表新结尾
{
end = end->next;
pos++;
}
ptr = end->next;//找到开始插入的节点
end->next = NULL;//截断为两个链表
tmp1 = ptr->next;//将后一个链表逆序,ptr是新的头
if(tmp1 != NULL){
tmp2 = tmp1->next;
}
ptr->next == NULL;//将单链表逆序,原来的头的next指针指向空,否则会形成回路
while(tmp1!=NULL){
tmp1->next = ptr;
ptr=tmp1;
tmp1=tmp2;
if(tmp2!=NULL){
tmp2 = tmp2->next;
}
}
pHead = ptr;//后半部分逆序后的头结点
tmp1 = head;
while(pHead != NULL){
pHead = ptr->next;//保存下一个位置
ptr->next = tmp1->next;
tmp1->next = ptr;
tmp1 = tmp1->next->next;
ptr = pHead;
}
return;
}
};