递归理解以及时间复杂度计算

article/2025/9/20 0:24:02

一.复杂度分析:

可以理解为递归的深度就是空间复杂度,时间复杂度就是O(T*depth),其中T是每个递归函数的时间复杂度,depth是递归深度.


#空间复杂度O(1)
def sum1_(n):res = 0for i in range(n+1):res+=ireturn res#递归 空间复杂度O(n)
def sum2_(n):if n == 0:return 0return n+sum2_(n-1)res1 = sum1_(n=10)
res2 = sum2_(n=10)
print('==res1:', res1)
print('==res2:', res2)

上式时间复杂度也为O(1*n)=O(n)

二.例子

1.计算x^n:


def pow(x, n):if n==0:return 1.t = pow(x, n//2)if n%2:return x*t*telse:return t*tres = pow(2,3)
print('res:', res)

递归深度:logn ,每个递归函数的时间复杂度为O(1),故时间复杂度为O(logn).

空间复杂度:logn

2.假如这里有 n 个台阶,每次你可以跨 1 个台阶或者 2 个t台阶,请问n个台阶有多少种走法?

第一步走了一个台阶或第一步走了两个台阶,到下一个台阶也是类似,故这是一个递归。

n个台阶就是,走了一个台阶后加剩下n-1台阶的走法,走了两个台阶后剩下n-2台阶的走法,

f(n)=f(n-1)+f(n-2)

终止条件:只剩一个台阶一种走法,只剩两个台阶两种走法,

f(1)=1,f(2)=2

def fun(n):if(n == 1): return 1elif (n == 2): return 2else:return fun(n - 1) + fun(n - 2)

每个递归函数的时间复杂度为O(1),空间复杂度:O(2^n), 故时间复杂度为O(2^n).

缺点:堆栈溢出、重复计算、函数调用耗时多、空间复杂度高等

防止递归造成堆栈溢出,加入深度,大于1000就不再溢出

depth=0
def fun(n):global depthdepth+=1print('depth=',depth)if (depth>1000): return -1if(n == 1): return 1elif (n == 2): return 2else:return fun(n - 1) + fun(n - 2)
print(fun(3))

存在大量重复计算:

优化思路1: 

递推,从下到上:

class Solution:def numWays(self, n: int) -> int:a,b=1,1for i in range(n):a,b = a+b,areturn b

思路2,将计算过的值存储在进行判断:


def fun(n,arr):if(n == 1): return 1elif (n == 2): return 2else:if arr[n]!=-1:return arr[n]else:arr[n] = fun(n - 1,arr) + fun(n - 2,arr)return arr[n]
n = 6
arr = [-1]*(n+1)
res= fun(n=n, arr=arr)
print('==res:', res)

3.递归实现全排列:

def swap(a, p, i):a[p], a[i] = a[i], a[p]return a#取第一个数,剩下的做排序,边界条件是开始索引p==终止索引q
def main(a, p, q):res = []def permute(a, p, q):if p == q:res.append(a.copy())print('res:', res)else:for i in range(p, q, 1):swap(a, p, i)permute(a, p+1, q)print('a:', a.copy())swap(a, p, i)#a还原成原顺序,比如2开头的结束了是2 1 3 需要还原成1 2 3 在吧3放在开头在排序print('==a:', a.copy())permute(a, p, q)print('==res:', res)#
# a = [1]
# a = [1, 2]
a=[1, 2, 3]
main(a, 0, len(a))class Solution:def permute(self, nums):""":type nums: List[int]:rtype: List[List[int]]"""def backtrack(first=0):# 所有数都填完了if first == n:res.append(nums.copy())for i in range(first, n):# 动态维护数组nums[first], nums[i] = nums[i], nums[first]# 继续递归填下一个数backtrack(first + 1)# 撤销操作nums[first], nums[i] = nums[i], nums[first]n = len(nums)res = []backtrack()return resa = [1, 2, 3]
sol = Solution()
res = sol.permute(a)
print('===res:', res)

4.递归实现快速幂

问题:求 a 的 b 次方对 p 取模的值

#a^b%p
def a_b_p(a,b,p):if b == 0:return 1elif b%2 == 1:#b是奇数return a*a_b_p(a, b-1, p)%pelse:#b是偶数temp = a_b_p(a, b//2, p)return (temp*temp)%pres = a_b_p(3,3,4)
print('==res:', res)

5.递归实现汉罗塔


#include <iostream>
#include <string>
#include <string.h>
#include <stdio.h>
using namespace std;
//a--from b--temp c--to
void hano(int n, char a, char b, char c);
int main(){hano(3, 'a', 'b', 'c');return 0;}
//a--from b--temp c--to
void hano(int n,char a, char b, char c){if(n==1){cout<<a<<"-->"<<c<<endl;}else{hano(n-1, a, c, b);//c为temp,a上面的n-1给bhano(1, a, b, c);//b为temp,a上面的1给chano(n-1, b, a, c);//a为temp,b上面的n-1给c}
}

加上盘子序号:

盘子从上到底是1到n

#include <iostream>
#include <string>
#include <string.h>
#include <stdio.h>
using namespace std;
//a--from b--temp c--to
void hano(int top, int n, char a, char b, char c);
int main(){hano(1, 3, 'a', 'b', 'c');return 0;}
//a--from b--temp c--to
void hano(int top, int n,char a, char b, char c){if(n==1){cout<<"盘子"<<top<<a<<"-->"<<c<<endl;}else{hano(top, n-1, a, c, b);//c为temp,a上面的n-1给bhano(top + n - 1, 1, a, b, c);//b为temp,a上面的1给chano(top, n-1, b, a, c);//a为temp,b上面的n-1给c}
}


http://chatgpt.dhexx.cn/article/pWBrBcaT.shtml

相关文章

递归的时间与空间复杂度

一、 递归的时间复杂度 递归算法的时间复杂度 递归次数 \times 每次递归的时间复杂度。 递归次数&#xff1a;可以通过画递归树&#xff0c;数递归树的节点数&#xff0c;得到递归次数。 二、递归的空间复杂度 递归算法的空间复杂度 递归深度 \times 每次入栈的空间…

【转】Tomcat相关面试题,看这一篇就够了!

转自公众号&#xff1a;Java思维导图 Tomcat相关的面试题出场的几率并不高&#xff0c;正是因为如此&#xff0c;很多人忽略了对Tomcat相关技能的掌握。下面这篇文章整理了Tocmat相关的系统架构&#xff0c;介绍了Server、Service、Connector、Container之间的关系&#xff0c…

10道Mybatis经典面试题,赶快上车吧!⚡⚡⚡⚡

1.Mybatis中#{}和${}的区别是什么&#xff1f; 1.1 #{}方式能够很大程度防止sql注入&#xff08;安全&#xff09;&#xff1b; ${}方式无法防止Sql注入。 1.2 在JDBC能使用占位符的地方&#xff0c;最好优先使用#{}&#xff1b; 在JDBC不支持使用占位符的地方&#xff0c;就…

mybatis面试题 一

一、MyBatis工作原理&#xff1f; 1、 创建SqlSessionFactory 2、 通过SqlSessionFactory创建SqlSession 3、 通过sqlsession执行数据库操作 4、 调用session.commit()提交事务 5、 调用session.close()关闭会话 1&#xff09;读取 MyBatis 配置文件&#xff1a;mybatis-c…

Java面试题Tomcat的优化经验

来源&#xff1a;传智论坛 Tomcat作为Web服务器&#xff0c;它的处理性能直接关系到用户体验&#xff0c;下面是几种常见的优化措施&#xff1a; 一、掉对web.xml的监视&#xff0c;把jsp提前编辑成Servlet。有富余物理内存的情况&#xff0c;加大tomcat使用的jvm的内存 二、服…

Tomcat相关面试题,看这篇就够了!保证能让面试官颤抖!

Tomcat相关的面试题出场的几率并不高&#xff0c;正式因为如此&#xff0c;很多人忽略了对Tomcat相关技能的掌握&#xff0c;下面这一篇文章最早发布在知识星球&#xff0c;整理了Tomcat相关的系统架构&#xff0c;介绍了Server、Service、Connector、Container之间的关系&…

【Tomcat专题】简单认识一下Tomcat总体架构

文章目录 什么是Tomcat&#xff1f;Tomcat的主要工作Tomcat总体架构连接器容器 请求定位流程 什么是Tomcat&#xff1f; 在Tomcat官方网站上是这样介绍的。 The Apache Tomcat software is an open source implementation of the Jakarta Servlet, Jakarta Server Pages, Jaka…

四张图带你了解Tomcat系统架构--让面试官颤抖的Tomcat回答系列!

俗话说&#xff0c;站在巨人的肩膀上看世界&#xff0c;一般学习的时候也是先总览一下整体&#xff0c;然后逐个部分个个击破&#xff0c;最后形成思路&#xff0c;了解具体细节&#xff0c;Tomcat的结构很复杂&#xff0c;但是 Tomcat 非常的模块化&#xff0c;找到了 Tomcat最…

Tomcat常见面试题

1、tomcat有哪些组件&#xff1f; 2、tomcat有哪些Connector&#xff1f; http ajp 3、tomcat的Valve的作用是什么&#xff1f; 给每一个虚拟主机定义访问日志 4、servlet的生命周期&#xff1f; Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过…

【金三银四】Tomcat面试题(2021最新版)

目录 前言 1、Tomcat的缺省端口是多少&#xff0c;怎么修改&#xff1f; 2、tomcat 有哪几种Connector 运行模式(优化)&#xff1f; 3、Tomcat有几种部署方式&#xff1f; 4、tomcat容器是如何创建servlet类实例&#xff1f;用到了什么原理&#xff1f; 5.tomcat 如何优化…

Tomcat面试题(2020最新版)

文章目录 Tomcat是什么&#xff1f;Tomcat的缺省端口是多少&#xff0c;怎么修改tomcat 有哪几种Connector 运行模式(优化)&#xff1f;Tomcat有几种部署方式&#xff1f;tomcat容器是如何创建servlet类实例&#xff1f;用到了什么原理&#xff1f;Tomcat工作模式Tomcat顶层架构…

「面试必背」Tomcat面试题(收藏)

「面试必背」Tomcat面试题&#xff08;建议收藏&#xff09; 2022-04-27 16:31java柚子茶 前言 在工作中&#xff0c;作为 Java 开发的程序员&#xff0c;Tomcat 服务器是大家常用的&#xff0c;也是很多公司现在正在用的。但是&#xff0c;在系统并发量比较大的情况下&…

Tomcat面试题(总结最全面的面试题)

Tomcat是什么&#xff1f; Tomcat 服务器Apache软件基金会项目中的一个核心项目&#xff0c;是一个免费的开放源代码的Web 应用服务器&#xff0c;属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试JSP 程序的首…

【面试】Tomcat面试题

文章目录 Tomcat是什么&#xff1f;Tomcat的缺省端口是多少&#xff0c;怎么修改怎么在Linux上安装Tomcat怎么在Linux部署项目Tomcat的目录结构类似Tomcat&#xff0c;发布jsp运行的web服务器还有那些&#xff1a;tomcat 如何优化&#xff1f;tomcat 有哪几种Connector 运行模式…

Linux面试问题---常用命令

Linux面试问题---常用命令 1、cd命令 用于切换当前目录&#xff0c;参数是要切换到的目录的路径。 Cd /root/Documents #切换到/root/Documents目录Cd ./path 切换到当前目录下的path目录 Cd ../path 切换到上层目录下的path目录 2、ls命令 查看文件与目录的命令 3、grep…

Linux命令面试突击

Linux 命令常见面试题总结。 其它面试知识点突击整理&#xff1a; 序号文章1Java基础面试突击2JVM面试突击3设计模式面试突击4并发编程面试突击5消息队列Kafka面试突击6Redis面试突击7计算机网络面试突击8Spring面试突击9Dubbo面试突击10MyBatis面试突击11操作系统面试突击12…

Linux面试题(2020最新版)

Java面试总结&#xff08;2021优化版&#xff09;已发布在个人微信公众号【技术人成长之路】&#xff0c;优化版首先修正了读者反馈的部分答案存在的错误&#xff0c;同时根据最新面试总结&#xff0c;删除了低频问题&#xff0c;添加了一些常见面试题&#xff0c;对文章进行了…

Linux面试问题

grep和find的区别&#xff1f; 所以简单点说说&#xff0c;grep是查找匹配条件的行&#xff0c;find是搜索匹配条件的文件。 find /dir -name filename grep的使用干货&#xff1a; ls -l | grep ^a 通过管道过滤ls -l输出的内容&#xff0c;只显示以a开头的行。 grep test…

Linux面试总结

一.常用命令 1.目录切换 cd / 切换到根目录 cd ../ 切换到上级目录 cd ~ 切换到home目录 2.查看目录 ls 列出当前目录下所有的文件 ls [路径] ls / 查看根目录 ls -l 相当于 ll 最常用的命令,用了表的方式列出当前目录的内容 3.查看当前目录 pwd- 4.创建一组空文件 touch 5.显…

Linux面试相关知识点看着一文就够了

今天和大家分享一下linux操作系统下主要用到的几个知识点&#xff0c;分别是&#xff1a;linux目录结构、linux常用命令、文件权限操作、服务操作、yum安装命令、docker服务、vim编译器、pymysql测试连接、用户及组命令、mysql创建用户和数据库 目录 一、linux目录结构 二、l…