206. 反转链表

128 阅读1分钟

[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,如果不对原来节点的信息进行保存,会造成数据的丢失。

总结

在链表上使用双指针,最最重要的一点是要挖掘出双指针的指向需要满足什么样的条件,才能符合我的要求。由于链表只能单项移动,那么就涉及到双指针要走的速度,起点等。在翻转链表中,双指针只需要保持相差一位,同速即可满足要求,至于其他情况,我们下来使用其他问题来讲解。