Given the
head
of a singly linked list, reverse the list, and return the reversed list.Example 1:
Input: head = [1,2,3,4,5] Output: [5,4,3,2,1]Example 2:
Input: head = [1,2] Output: [2,1]Example 3:
Input: head = [] Output: []Constraints:
- The number of nodes in the list is the range
[0, 5000]
.-5000 <= Node.val <= 5000
Follow up: A linked list can be reversed either iteratively or recursively. Could you implement both?
题目大意:
这道题的大意是让你将给定的一个链表反转
实现思路:
设置三个指针,分别为f(first),s(second),t(third),依次指向前一个被反转的结点,当前被反转的结点,和下一个结点。并将链表顺次向后反转。
实现代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* f=head;
ListNode* s=NULL;
ListNode* t=NULL;
if(f&&f->next) s=f->next; //此处判断一定要看f是否为空
if(s&&s->next) t=f->next->next; //注意判断s是否为空
while(s&&t){
s->next=f;
f=s;
s=t;
t=t->next;
}
if(!t&&s) s->next=f;
else if(!t&&!s) s=f;
if(head) head->next=NULL; //看head是否为空,并且最后指针要指向空
return s;
}
};
这里要特别注意一下17,18,27行
17,18,27行如果不先判断指针是否为空,会报错。以17行为例,如果f=NULL,那么判断f->next就等价于判断NULL->next,显然是不对的。
同时在27行要特别注意,在最后的实现,要让最初的head指针指向空,不能让它随便指,很容易出问题,因此也会报错。
又上网查了一下,发现还有一些方法。
第一个是将我的三个指针依次前移,可以避免极度繁琐的判断。
代码如下:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* f=NULL;
ListNode* s=head;
ListNode* tmp=NULL;
while(s){
tmp=s->next;
s->next=f;
f=s;
s=tmp;
}
return f;
}
};
这样写法虽然简单了不少。
第二种方法:
头插法:也就是新建一个哑结点,依次将结点连接在这个哑结点上。
代码如下:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* dummy=(ListNode*)malloc(sizeof(struct ListNode));
dummy->next=NULL;
ListNode* cur=head;
ListNode* tmp=NULL;
while(cur){
tmp=cur->next;
cur->next=dummy->next;
dummy->next=cur;
cur=tmp;
}
return dummy->next;
}
};
还是要注意一点,为dummy分配完空间后要给出初值,即dummy->next=NULL,不然会报错。