[206. 反转链表]
「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。
题目描述
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例
示例1 :
输入: head = [1,2,3,4,5]
输出: [5,4,3,2,1]
示例 2:
输入: head = [1,2]
输出: [2,1]
示例 3:
输入: head = []
输出: []
提示:
- 链表中节点的数目范围是
[0, 5000] -5000 <= Node.val <= 5000
进阶: 链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
思路
这道题在之前的总结文章已经简单讨论过了,我们这次主要是借这道题目来讨论一下双指针在链表上的使用。之前双指针的题目我们都是在数组和字符串上面,它们都支持后序遍历和随机访问,在有题目上体现不出双指针的优点和强大之处。而双指针在链表的使用可谓是最强的。翻转链表是在其上面的最为好理解的使用。递归法从本质上,是属于栈的使用。在这题上,双指针就是通过指向前后两个节点,一个一个改变他们的指向,来完成目的
代码实现
/** * 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* temp;
ListNode* cur=head;
ListNode* pre=NULL;
while(cur){
temp=cur->next;
cur->next=pre;
pre=cur;
cur=temp;
}
return pre;
}
};
在代码上面看可以看到定义了3个指针,有点疑惑,但是可以发现,temp指针并没有在链表上进行具体操作,只是一个记录的作用,因为在改变cur->next,如果不对原来节点的信息进行保存,会造成数据的丢失。
总结
在链表上使用双指针,最最重要的一点是要挖掘出双指针的指向需要满足什么样的条件,才能符合我的要求。由于链表只能单项移动,那么就涉及到双指针要走的速度,起点等。在翻转链表中,双指针只需要保持相差一位,同速即可满足要求,至于其他情况,我们下来使用其他问题来讲解。