重排链表 几个关键点:
1. 双指针(快慢指针找中点)(用于反转后一部分)
2. 反转后一部分 (reverse函数)
3. 合并链表
合并的时候在笔试的时候想了一种比我之前想的简单的方法
从slow->next开始反转 而不是slow,如果从slow开始反转实际上会多插入最后一次 就会复杂一点
同时保存slow作为最后一个结点,断开slow后面的节点 进行合并
然后合并的时候注意 使用后面的链表p作为循环结束的条件,因为p为空说明所有的链表已经插入前面的链表了。
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode(int v):val(v),next(NULL){}
};
ListNode* reverseList(ListNode *head)
{
ListNode *cur = head, *pre = NULL, *nxt =NULL;
while(cur)
{
nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
return pre;
}
void helper(ListNode * head)
{
//快慢指针
ListNode *slow=head,*fast=head;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
}
ListNode *newNode = slow->next;
slow->next=NULL;
ListNode *newHead = reverseList(newNode);
ListNode *cur=head,*nxt=NULL,*p=newHead,*pnxt=NULL;
while(p)
{
pnxt = p->next;
nxt = cur->next;
cur->next = p;
p->next = nxt;
cur = nxt;
p = pnxt;
}
ListNode *res =head;
cout<<"[";
while(res->next)
{
cout<<res->val<<",";
res=res->next;
}
cout<<res->val<<"]";
}
int main()
{
string str;
getline(cin, str);
int n = str.size();
string strlist = str.substr(8,n-9);
//建立链表
if(strlist.empty())
{
cout<<"error"<<endl;
return 0;
}
if(strlist.size()==1)
{
cout<<"["<<strlist[0]<<"]";
return 0;
}
stringstream ss(strlist);
string p;
ListNode *dummy = new ListNode(-1);
ListNode *pp = dummy;
while(getline(ss,p,','))
{
int num = stoi(p);
ListNode *numNode = new ListNode(num);
//cout<<numNode->val<<endl;
pp->next = numNode;
pp = numNode;
}
ListNode *head=dummy->next;
ListNode *res =head;
//head = [1,2,3,4,5,6]
helper(head);
return 0;
}