剑指OFFER第24题--反转链表

本文详细介绍了两种链表反转的方法:迭代法和递归法。迭代法通过双指针技巧实现链表的反转,而递归法则利用递推公式简化问题,提供了一种直观的理解方式。

解法一:迭代法

/*
双指针以迭代的形式反转链表
*/
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre=nullptr;
        ListNode* cur=head;
        while(cur){
            ListNode* next=cur->next;
            cur->next=pre;
            pre=cur;
            cur=next;
        }
        return pre;
    }
};

 解法二:递归法

        其实写递归不能总想着去把递归平铺展开,这样脑子里就会循环,一层一层往下调,然后再一层一层返回,试图想搞清楚计算机每一步都是怎么执行的,这样就很容易被绕进去。对于递归代码,这种试图想清楚整个递和归过程的做法,实际上是进入了一个思维误区。只要找到**递推公式**,我们就能很轻松地写出递归代码。

        递归第一准则:所有的递归问题都可以用递推公式来表示。

        递归第二准则:递归是一种关于某个重复动作(完成重复性的功能)的形式化描述。具体点讲,如果一个问题 A 可以分解为若干子问题 B、C、D,你可以假设子问题 B、C、D 已经解决,在此基础上思考如何解决问题 A。而且,你只需要思考问题 A 与子问题 B、C、D 两层之间的关系即可,不需要一层一层往下思考子问题与子子问题,子子问题与子子子问题之间的关系(也就是说,递归只能考虑当前层和下一层的关系,不能继续往下深入)。我们需要屏蔽掉递归细节,理解为完成了某种功能的形式化描述即可。

         令F(node)为问题:反转以node为头节点的单向链表;
         一般,我们需要考虑F(n)和F(n-1)的关系,那么这里,如果n代表以node为头节点的单向链表,那么n-1就代表以node.next为头节点的单向链表.
        所以,我们令F(node.next)为问题:反转以node.next为头节点的单向链表;
         那么,F(node)和F(node.next)之间的关系是?这里我们来简单画个图,假设我们反转3个节点的链表:
1 -> 2 -> 3
        那么,F(node=1)=F(node=2)+?
        这里假设子问题F(node=2)已经解决,那么我们如何解决F(node=1):
        很明显,我们需要反转node=2和node=1, 即 node.next.next=node; 同时 node.next=null;
        所以,这个问题就可以是:F(node=1)=F(node=2)+ 反转node=2和node=1

该递归思想参考
链接:https://leetcode.cn/problems/fan-zhuan-lian-biao-lcof/solution/kan-bu-dong-di-gui-de-kan-guo-lai-xi-wan-1akq/

/*
递归方法
*/
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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值