题目描述
给定一个单链表的头结点pHead(该头节点是有值的),长度为n,反转该链表后,返回新链表的表头。
数据范围:0<=n<=1000
要求:空间复杂度O(1),时间复杂度O(n)
题目来源
略
输入描述
输入分为2段,第一段是入环前的链表部分,第二段是链表环的部分,后台会根据第二段是否为空将这两段组成一个无环或者有环单链表
输出描述:
返回链表的环的入口结点即可,我们后台程序会打印这个结点对应的节点值;若没有,则返回对应编程语言的空结点即可。
示例1
输入:
{1,2,3}
输出:
{3,2,1}
示例2
输入:
{}
输出:
{}
思路
设置3个指针,链表指针list,下一结点指针p,前一结点a。循环执行以下四步:
1.将链表指针的next指向a:list->next=a;
2.a指针指向当前结点: a= list;
3.链表指针指向下一结点p:list=p;
4.p结点指向下一个节点:p= p->next;
具体实现
#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <algorithm>//引入sort()函数
#include <cstring>//调用strcmp()函数
#include "linklist.cpp"
using namespace std;
int insert_end(linklist &l,int val)//执行插入数据到链表尾部操作,linklist &l传的是尾指针
{
linklist p ;
p = new node;
p->data = val;
p->next = 0;
l->next = p;
l = p;
return 1;
}
int main()
{
string str;
string temp;
int tempval;
linklist p ;
linklist a ;
linklist listend ;//尾指针,仅在建立链表时使用
linklist list ;
///链表初始化,有一个空的头结点
list = new node;
list->data = 0;
list->next = 0;
listend =list;
p=list;
cout << "input: " << endl;
cin>>str;
for(int i =0;i<str.length();i++)
{
if(str[i]==' ')
{
continue;
}
if(str[i]=='[')
{
continue;
}
if(str[i]==','||str[i]==']')
{
//cout<<"push temp="<<temp<<endl;
tempval = atoi(temp.c_str());
insert_end(listend,tempval);
temp="";
continue;
}
temp += str[i];
}
以上都是读取输入,初始化链表阶段
listend =list;
list = list->next;//这才是题目要求的无头节点的表。
delete listend;
p = list;
if(p->next)
{
a=p->next;
if(a->next)//如果有第三个节点
{
//cout<<"a->next->data="<<a->next->data<<endl;
list->next = 0;
p=a->next;
for(p->next;p->next;p=p->next)
{
a->next=list;
list = a;
a=p;
//cout<<list->data<<endl;
}
a->next=list;
p->next =a;
list = p;
}
else{ //如果只有2个节点
a->next=list;
list->next = 0;
list = a;
}
}
cout<<"["<<list->data<<",";
for(list->next;list->next;list=list->next)
{
cout<<list->next->data<<",";
}
cout <<"\b]"<<endl;
return 0;
}
时间复杂度
O(n)
小结
1.首次尝试自己建链表,发现比想象的简单。
2.多指针操作的逻辑要理清。