题目
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
题解
笔记
思路:
1.开辟新空间的做法很简单,每次用指针p遍历链表,将p加到新链表后面
2.双指针思路(参考力扣题解):
2.1 定义两个指针:pre和cur;pre在前cur在后。
2.2 每次让 pre的next指向cur,实现一次局部反转
2.3 局部反转完成之后,pre 和 cur 同时往前移动一个位置
2.4 循环上述过程,直至 pre 到达链表尾部
其实双指针还是利用了第3个指针作为tmp中间变量,用来暂时保存pre->next
然后pre->next = cur, cur = pre, 最后pre = tmp;
双指针动画演示如下:(参考力扣)
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
//双指针
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==nullptr)
return head;
ListNode* p = nullptr;
ListNode* q = head;
while(q!=nullptr){
ListNode *tmp = q->next;
q->next = p;
p = q;
q = tmp;
}
return p;
}
};
//单独开辟空间存放的做法
class Solution1 {
public:
ListNode* reverseList(ListNode* head) {
ListNode* l;
if(head!=nullptr){
l = new ListNode(head->val);
}
else
return l;
ListNode* p = head;
while(p->next!=nullptr){
p = p->next;
ListNode* tmp = new ListNode(p->val);
tmp->next = l;
l = tmp;//头节点指向tmp
}
return l;
}
};