题目
Reverse a singly linked list.
反转单链表。
方法一
思路
用容器存储链表中的值,使用reverse反转,再存回链表中。代码
//C++
class Solution{
public:
ListNode* reverseList(ListNode* head){
if(head==NULL||head->next==NULL) return head;
vector<int> v;
ListNode* p=head;
while(p!=NULL)
{
v.push_back(p->val);
p=p->next;
}
reverse(v.begin(),v.end());
p=head;
for(int i=0;p!=NULL;i++)
{
p->val=v[i];
p=p->next;
}
return head;
}
};
方法二
思路
<1>设置一个新结点s(初始化为NULL),同时令指针q指向head的后续结点。
<2>head结点利用q不断沿着链表遍历,而在此过程中不断把自己插入结点s之前,s又更新为新插入的结点。
<3>所以越是在链表后面的结点越是跑到了前面,便完成了反转。代码
//C++
class Solution{
public:
ListNode* reverseList(ListNode* head){
if(head==NULL||head->next==NULL) return head;
ListNode* s=NULL;
ListNode* q;
while(head!=NULL)
{
q=head->next;
head->next=s;
s=head;
head=q;
}
return s;
}
};
方法三
思路
利用函数调用不断向后实现两两交换。实现交换的前者是已经交换好了的部分链表,而后者是未进行交换的另一部分链表,不断从后者中的表头指向前者的表尾,由此实现把未进行交换的链表中的结点一个个加入到交换好了的链表中。代码
//C++
class Solution{
public:
ListNode* reverseList(ListNode* head){
if(head==NULL||head->next==NULL) return head;
ListNode* p=head->next;
head->next=NULL;
return reverseTwo(head,p);
}
ListNode* reverseTwo(ListNode* l1,ListNode* l2)
{
if(l2==NULL) return l1;
ListNode* q=l2->next;
l2->next=l1;
return reverseTwo(l2,q);
}
};
方法四
思路
递归,与方法三类似,这里把后者当成一个交换好了的整体,前者作为接下来要处理的结点。代码
//C++
class Solution{
public:
ListNode* reverseList(ListNode* head){
if(head==NULL||head->next==NULL) return head;
ListNode* ans=head;
ListNode* p=head->next;
while(ans->next!=NULL) ans=ans->next;
head->next=NULL;
reverseTwoSide(head,p);
return ans;
}
ListNode* reverseTwoSide(ListNode* l1,ListNode* l2)
{
if(l2==NULL) return l1;
else
{
ListNode* tail=reverseTwoSide(l2,l2->next);
tail->next=l1;
return l1;
}
}
};