从基本概念到面试解决方案,小白程序员成长之路!

在计算机编程的世界中,递归是一种强大且神奇的工具。是一种算法设计的方法,允许函数在其自身内部调用。递归使得解决复杂问题变得更加简单,也让我们更深入地理解计算机科学中的重要概念。本文将介绍递归的概念,示例和应用,帮助你更好地理解这个令人着迷的主题。同时,有关递归的问题在面试中也常被考到,本文也将举例分析!

概念介绍

什么是递归?

递归是一种函数调用自身的编程技术。这意味着在函数内部,它可以通过调用自身来解决问题。递归的核心思想是将一个大问题分解成更小的、相似的子问题,然后再次应用相同的算法来解决这些子问题。这个过程继续,直到达到问题的基本情况(通常是一个简单的问题)并返回结果。递归函数包括两个关键部分:基本情况和递归情况。

基本情况和递归情况

基本情况是递归算法的终止条件。在递归函数中,当满足基本情况时,函数不再调用自身,而是返回一个已知的结果。这防止了递归函数无限循环,导致栈溢出错误。基本情况通常是一个简单的问题,可以立即解决。

递归情况则是将大问题分解为更小问题的部分。在递归函数中,它会调用自身,但使用不同的参数,通常是问题规模减小的方式。递归情况将问题不断分解,直到达到基本情况。

示例:计算阶乘

一个经典的递归示例是计算阶乘。阶乘是正整数的乘积,例如5的阶乘(5!)等于5 * 4 * 3 * 2 * 1。下面是一个使用递归来计算阶乘的示例:

JavaScript
复制代码
// 5! == 5*4*3*2*1

function mul (n) {
    if (n === 1) {
        return 1
    }
    return n * mul(n - 1)
}
console.log(mul(5));

在这个示例中,基本情况是n等于1时,返回1。递归情况是n乘以factorial(n - 1)的结果,不断减小n的值,直到达到基本情况。

示例:斐波那契数列

斐波那契数列是一个数学序列,其中每个数字都是前两个数字之和。序列的前几个数字通常是0、1、1、2、3、5、8、13,以此类推。下面是一个使用递归计算斐波那契数列的示例:

JavaScript
复制代码
//斐波那契数列 1 1 2 3 5 8 13 21...
function fib(n) {
    if (n <= 1) return n;
    return fib(n - 1) + fib(n - 2);
}

console.log(fib(6));

在这个示例中,基本情况包括 n 为 0 或负数时返回 0,以及 n 为 1 时返回 1。递归情况则是 n 等于前两个斐波那契数的和,通过不断减小 n 的值,直到达到基本情况。这个函数可以用来计算斐波那契数列的第 n 个数字。

例如,如果你调用 fibonacci(6),将会得到结果 8,因为第六个斐波那契数是 8。

需要注意的是,虽然递归是一种直观的方式来计算斐波那契数列,但对于大的 n 值,递归方法可能会导致性能问题,因为它会多次计算相同的子问题。在这种情况下,更高效的方法是使用迭代或动态规划,在后续的文章中我们将会聊到~

递归的优点

递归具有一些独特的优点,使得它在某些情况下成为最佳选择。首先,递归能够让问题更容易理解和表达。通过将问题分解为更小的子问题,你可以更清晰地思考和解决它们。其次,递归有助于重用代码。递归函数可以在多个地方调用自身,而不需要编写重复的代码。最后,递归有时可以更简洁地解决问题,而无需显式的循环结构。

递归的缺点

尽管递归强大,但它也有一些缺点。递归可能会导致性能问题,因为每次递归调用都需要在堆栈中保留上下文信息,这可能会导致堆栈溢出或内存消耗问题。此外,递归代码有时可能不太直观,难以理解,因此需要慎重选择使用递归的情况。

尾递归

一种特殊类型的递归称为尾递归。在尾递归中,递归调用发生在函数的最后一条语句,且没有任何后续操作。这种情况下,编译器或解释器通常可以对递归进行优化,将其转化为迭代形式,减少堆栈的使用。尾递归是一种有效减少递归性能问题的方式。

注意事项

在使用递归时,需要注意一些关键事项。首先,确保你的递归函数能够收敛到基本情况,否则它将无限循环。其次,谨慎选择使用递归,确保它是解决问题的最佳方法。最后,注意性能问题,特别是在处理大规模数据时,可能需要考虑使用迭代方法或优化。

递归的应用

递归在计算机科学中有许多应用,包括树数据结构的遍历、图算法、分治策略和快速排序等。它们在解决涉及层次结构的问题时非常有用,因为递归允许问题在不同层次上进行拆分和解决。

然而,递归并不适用于所有问题。在某些情况下,递归可能会导致性能问题,因此需要谨慎使用。此外,过深的递归调用可能导致栈溢出错误,因此需要确保基本情况能够满足。

面试相关!

在面试中面试官问到递归相关时,通常会问这么一个问题:给你一个下方样式数组,对其进行操作使它扁平化输出

JavaScript
复制代码
var arr = [1,[2,[3,4]]] // 希望输出[1,2,3,4]

解决的办法有很多,首先想到的方法当然是ES6引入的flat()函数

JavaScript
复制代码
var arr = [1,[2,[3,4]]] // 希望输出[1,2,3,4]

var newArr = arr.flat(2)// 使数组扁平化,2表示深度,如果不写默认为1,如果写Infinity则表示无限深度
console.log(newArr);

image.png 完美解决…但是通常,面试官会告诉你不得使用flat()函数… 所以我们可以使用下列方法:

JavaScript
复制代码
var arr = [1,[2,[3,4]]] // 希望输出[1,2,3,4]

function flatten (arr) {
    var  result = []// 定义一个空数组
    for (let i = 0; i < arr.length; i++) {// 遍历目标数组arr
        if (Array.isArray(arr[i])) {// 如果数组中的元素是数组的话
            // 递归调用arr内部数组,并将递归调用返回的深层数组与上一层数组连接
            result = result.concat(flatten(arr[i]))
            
        } else {
            result.push(arr[i])// 如果不是数组的话,直接push到result中
        }
    }
    return result// 返回result
}

console.log(flatten(arr));

该方法通过递归的思想,因为将数组执行遍历过程中遇到的元素为数组时,我们将该元素当作一个需要继续遍历的数组,就好像《盗梦空间》中的多层梦境,在遍历每一层梦境的时候你需要执行高度相似的操作{即,定义一个空数组->遍历该数组中的元素->元素是数组时,进行递归调用flatten函数,并将返回的更深层的数组与上一层数组拼接(元素不是数组时,直接放入result[]中)->返回进行操作后的result数组,即为所求}

image.png 成功达成需求! 但是代码貌似有点太长了,此时可以使用reduce()函数来简化代码:

JavaScript
复制代码
var arr = [1,[2,[3,4]]]

function flatten(arr){
    return arr.reduce(function(pre, item){// pre是上一次的返回值,item是当前值
       return pre.concat(Array.isArray(item)?flatten(item):item)// 如果item是数组的话,递归调用flatten函数,否则直接concat到pre中
    },[])// []是初始值,如果不写默认为数组的第一个值
}
console.log(flatten(arr));// [ 1, 2, 3, 4 ]

image.png 至此,你已经成功拿下在面试中考到你使用递归思想解决扁平化的问题!

结论

递归是计算机编程中的强大工具,它可以帮助解决复杂问题,提高代码的可读性和重用性。通过合理地选择递归情况和基本情况,你可以构建出高效且清晰的递归算法。同时,也要小心递归可能引发的性能问题,确保适当地使用递归来解决问题。掌握递归是成为优秀程序员的重要一步,它将为你打开解决各种问题的新世界。

这里给大家分享一份Python全套学习资料,包括学习路线、软件、源码、视频、面试题等等,都是我自己学习时整理的,希望可以对正在学习或者想要学习Python的朋友有帮助!

优快云大礼包:全网最全《全套Python学习资料》免费分享🎁

😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓

👉优快云大礼包🎁:全网最全《Python学习资料》免费分享(安全链接,放心点击)👈

1️⃣零基础入门

① 学习路线

对于从来没有接触过Python的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

② 路线对应学习视频

还有很多适合0基础入门的学习视频,有了这些视频,轻轻松松上手Python~在这里插入图片描述

③练习题

每节视频课后,都有对应的练习题哦,可以检验学习成果哈哈!
在这里插入图片描述
因篇幅有限,仅展示部分资料

2️⃣国内外Python书籍、文档

① 文档和书籍资料

在这里插入图片描述

3️⃣Python工具包+项目源码合集

①Python工具包

学习Python常用的开发软件都在这里了!每个都有详细的安装教程,保证你可以安装成功哦!
在这里插入图片描述

②Python实战案例

光学理论是没用的,要学会跟着一起敲代码,动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。100+实战案例源码等你来拿!
在这里插入图片描述

③Python小游戏源码

如果觉得上面的实战案例有点枯燥,可以试试自己用Python编写小游戏,让你的学习过程中增添一点趣味!
在这里插入图片描述

4️⃣Python面试题

我们学会了Python之后,有了技能就可以出去找工作啦!下面这些面试题是都来自阿里、腾讯、字节等一线互联网大厂,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
在这里插入图片描述
在这里插入图片描述

5️⃣Python兼职渠道

而且学会Python以后,还可以在各大兼职平台接单赚钱,各种兼职渠道+兼职注意事项+如何和客户沟通,我都整理成文档了。
在这里插入图片描述
在这里插入图片描述
上述所有资料 ⚡️ ,朋友们如果有需要 📦《全套Python学习资料》的,可以扫描下方二维码免费领取 🆓
😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓

👉优快云大礼包🎁:全网最全《Python学习资料》免费分享(安全链接,放心点击)👈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值