小白学算法(4)之递归篇

183 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

小白学算法(4)-递归

递归是将重复步骤进行简化的利器--无邪苦

递归三部曲

1.找中止条件

2.找返回值

3.找本层递归应该做什么

对于初学递归的同学,肯定是很迷糊的,因为他们想的太深,总会一层一层找到最后一层,然后返回值来到上一层,这样就导致都不知道在干嘛。

因为我也是这样的 🥲,但以后写递归时,请务必记住这三部曲,接下来就通过实例来进行讲解。

1.斐波拉契

这道题是很经典的问题,因为它的解法多样,这里我们讲解递归,所以使用递归。

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1

1)找到递归条件

通过该数列知道n<2时n的值就等于数列值,易得

if(n<2)
    return

2)找返回值

返回值上面的题中也写出来了F(n) = F(n - 1) + F(n - 2),其中 n > 1

return fib(n-1) + fib(n-2);

3)本层递归应该做什么

斐波那契并没有什么操作,所以本层没有操作

4)完整代码

int fib(int n){
    if (n<2) { 
        return n;
    } else {
        return fib(n-1) + fib(n-2);
    }   
}

虽然可以使用递归解出斐波那契数列,但是它的解题效率非常低,所以很多时候会导致超时,下图也看得到进行了很多无意义的操作,但本体只是为大家介绍递归方法而已,所以想要知道其他更好的解法,可以去百度一手,此处不介绍。

在这里插入图片描述

2.

通过上面的引入,相比各位帅读者觉得递归很简单,但是实际递归很麻烦,因为它的一个关键点找返回值和本层做什么经常不好找到,如下题

24. 两两交换链表中的节点 - 力扣(LeetCode)

head = [1,2,3,4]
输出:[2,1,4,3]

1)找递归条件

面对链表问题,并且参数是head 头节点的时候,

第一个终止条件便是此时head是否为空 head==NULL

题目说明是进行两两交换所以此时链表只有一个节点就自然结束了 head->next=NULL

综上

if(head==NULL||head->next==NULL)
    return head;

2)找返回值

这一步找起来很麻烦,不知道返回什么,可以看下本函数的返回值ListNode*一个节点,但返回什么节点

两两交换,那么肯定是两个节点一组,我们把实例分为两组

[1,2,3,4]->[1,2] ,[3,4] 进行交换

[2,1],[4,3] ,我们知道节点是数据域+指针域,那么数据域倒是交换了,那么指针域呢

所以我们就明白了,返回的节点是下一组的头节点,然后通过本组的后一个节点进行连接,这样就成功完成转换了

//进行分组,那么函数传入的参数肯定是下一组的头节点
ListNode *next=head->next;
//交换后 该组的后一个节点肯定就是之前头节点撒,所以是head-next
head->next=swapPairs(next->next);

3)本次递归做什么

继续上个步骤

分了组后并且进行了连接,此时情况就是

[2,1->4,3]

这样两组就连接在一起了,但是我们一组里面的两个节点没有连接啊

//此时 [2->1->4,3],有帅读者说4怎么不跟3连接,😉因为那是下一层干的事了,我们只关注这一层,递归切忌跑其他层了
next->next=head;

4)结束

转换后的链表由 [1->2]--->[2->1],所以原本的头节点便不是头节点了
return next;

5)完整代码

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        //1.找递归终止条件
        if(head==NULL||head->next==NULL)
            return head;
        //2.找返回值
        ListNode *next=head->next;
        //进行下一部分的遍历 那么头节点就是下下个节点
        head->next=swapPairs(next->next);
        //3.本次递归做什么
        //递归后 下一个节点就成为上一个节点
        next->next=head;
        return next;
    }
};

通过一易一中等题的解释,各位帅读者是否对递归有了一个很好的了解,希望给你带来收获,感谢观看。