leedcode206 反转链表

leedcode206 反转链表,第1张

文章目录
  • 反转链表
    • 解法一:迭代
    • 解法二:递归

反转链表

题目描述:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。



示例:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

解法一:迭代

由题目很容易想到,可以直接修改指针指向。


例如:本来是1->2,那么只需要将指针指向反转即可,即1<-2
若为1->2->3->4->5,那么直接依次进行反转,最终得:1<-2<-3<-4<-5

这种方法需要额外占有变量进行存储,因为每次修改指针指向后,链表已经断裂,无法或许下个结点的信息。


例如:对1->2->3->4->5在修改节点1的指针指向时,此时修改之后为null<-12->3->4->5,此时想要继续修改节点2的指针指向时,已经无法获取指向节点2的指针了。


另外,在修改节点2的指针时,需要知道节点2前一个节点(即节点1需要将其指向前一个节点,1<-2)。


所以我们首先需要一个额外变量存储当前节点的next,另外还需要一个节点存储当前节点的prev,下面看图解。


修改节点1的指针指向:

继续修改下一个节点指针,变量pfrontptmp均做出相应修改:

代码如下:

/**
 * 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* p = head;
        ListNode* pfront = nullptr;
        while(p != nullptr){
            ListNode* tmp = p->next;
            p->next = pfront;
            pfront = p;
            if(tmp == nullptr)
                break;
            p = tmp;
        }
        return p;
    }
};
解法二:递归

递归的解法比较难想到,官方的题解也给的很明确,这里我看了评论区又自己画图理解了一下,觉得还可以。


大致思路就是:
若初始链表为:

而我们此时 n k + 1 n_{k+1} nk+1之后的均已经反转,且我们所处位置为 n k n_k nk

那么我们所需要做的就是首先修改 n k n_{k} nk n k + 1 n_{k+1} nk+1之间的指针:nk->next->next = nk
然后修改 n k n_{k} nk的指针:nk->next = null

代码如下:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (!head || !head->next) {
            return head;
        }
        ListNode* newHead = reverseList(head->next);
        head->next->next = head;
        head->next = nullptr;
        return newHead;
    }
};

假设原始链表为1->2->3->4->5,自己推了一遍函数调用过程:

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/562785.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-02
下一篇 2022-04-02

发表评论

登录后才能评论

评论列表(0条)

保存