题目内容
输入一个链表,反转链表后,输出新链表的表头。
题目分析
还是老样子,单向链表,但是需要把链表原来的尾结点作为头结点,且原来的next指针需要指向自己的上一个结点,原来头结点的next指针指向NULL。
常规且比较暴力的思路是,借助数组,先从头到尾遍历找到尾结点,然后从尾到头依次修改next指针。而稍微具有技巧性的则是从网上学习到的三指针法。
解题
暴力解法
主要思路如下:
- 从头到尾遍历链表将结点依次赋值给数组并记录链表长度;
- 从尾到头倒序修改结点的next指针;
- 单独修改原头结点的next指针,指向NULL。
代码
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead == NULL)
return NULL;
ListNode* node[10010];
int length = 0;
while(pHead != NULL){
node[length++] = pHead;
pHead = pHead->next;
}
for(int i = length-1; i > 0; i--){
node[i]->next = node[i-1];
}
node[0]->next = NULL;
return node[length-1];
}
};
三指针法
主要步骤不方便用语言描述,改为图片叙述,以三个结点的链表为例,定义三个指针,分别为preNode、nowNode、nextNode;
ListNode* preNode = NULL;
ListNode* nowNode = pHead;
ListNode* nextNode = nowNode->next;
过程如图
代码
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead == NULL)
return NULL;
ListNode* preNode = NULL;
ListNode* nowNode = pHead;
ListNode* nextNode = nowNode->next;
while(nowNode!=NULL){
nowNode->next = preNode;
preNode = nowNode;
nowNode = nextNode;
nextNode = nextNode->next;
}
return preNode;
}
};
递归解法
主要步骤不方便用语言描述,改为图片叙述,以三个结点的链表为例,过程如图
代码
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
// 处理链表为空或仅有一个结点时的情况,同时为了找到尾结点时终止递归
if(pHead == NULL || pHead->next == NULL)
return pHead;
ListNode* EndNode = ReverseList(pHead->next);
pHead->next->next = pHead;
pHead->next = NULL;
return EndNode;
}
};
以上思路为个人想法和网络各位大佬的题解的结合,欢迎讨论与指正。