206 反转链表

在这里插入图片描述

解题思路可以有两种方法:递归 or 迭代。

\qquad 迭代:通过使用for循环遍历,完成目标。方法直观,容易理解。
\qquad 递归:通过函数调用其自身,完成目标。递归最复杂、最重要的部分就是递归函数的构建,构建递归函数可以从以下几方面考虑:
\qquad\qquad 1)函数的终止条件的设立。
\qquad\qquad 2)目标拆解后,函数每一步需要重复执行的操作。
\qquad\qquad 3)不同递归层级间的信息传递,可借助参数、返回值、外部变量等。

递归思路:
\qquad 一开始的思路,从刚才上面三个角度分析:
\qquad 1)当前head为最后一个节点时,返回head,作为翻转后链表的表头。
\qquad 2)每一步重复将当前head添加到新链表的末尾。
\qquad 3)观察可发现,完成每一步的操作需要两个信息:
\qquad\qquad 1 - 翻转后链表的表头,用于题目输出,只能作为递归函数的返回值传递。
\qquad\qquad 2 - 翻转后链表的末尾,用于重复将当前节点添加到链表末尾,被函数各层调用使用,一开始的思路是,是用全局变量去存储链表末尾,并在每次操作后不断更新。

优化思路:
\qquad 思路大致相同,但是能否优化无需使用全局变量来存储链表末尾?
\qquad 可以利用链表本身的特性,找到链表的末尾,如下所示:
\qquad\qquad 1 → \rightarrow 2 → \rightarrow 3 → \rightarrow 4 → \rightarrow 5 \qquad (原本的链表)
\qquad\qquad 1 → \rightarrow 2 → \rightarrow 3 ← \leftarrow 4 ← \leftarrow 5 \qquad (部分反转的链表)
\qquad 现在,函数递归到节点2,如何找到翻转链表的末尾?从图中可以很直观的理解:
\qquad end node = 2 -> next, 只需要将 2 -> next -> next = node 2,便可以将2翻转:
\qquad\qquad 1 → \rightarrow 2 ← \leftarrow 3 ← \leftarrow 4 ← \leftarrow 5 \qquad

\qquad 另外需要注意的点,由于每次操作是重复的,如果仅仅改变指针的指向会导致反转后的链表未能指向nullptr,因此在每一步操作中,需额外将反转链表末尾指向nullptr

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

迭代思路:
\qquad while循环遍历一次链表,对于当前每个节点node,都有上一个节点prev,和下一个节点next。对于每个节点所需要做的操作就是:
\qquad 1)记录下一个节点next
\qquad 2)改变当前节点指向,指向上一个节点node -> next = prev
\qquad 3)更新prev = nodenode = next

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* node = head;
        ListNode* prev = nullptr;
        while(node != nullptr)
        {
            ListNode * temp = node->next;
            node->next = prev;
            prev = node;
            node = temp;
        }
        return prev;
    }
}; 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值