数据结构与算法-递归回溯分治

news2024/12/23 14:57:37
        引入思考:

        1.微信分销系统中有一个返利,大家应该都知道,比如B是A的下线,C是B的下线,那么在分钱返利的时候A可以分B,C的钱,这时候我们是不是就要分别找B,C的最后上级。这个问题我们一般怎么来解决呢?

        2.斐波那契数列: 1 1 2 3 5 8 13 21 有什么特点? 从第三个数开始 就等于前面两个数相加; 数论思想:利用数学公式或者定理或者规律求解问题; f(n) = f(n-1) + f(n-2)

        什么是递归?

                1.递归的定义: 递归是一个非常重要的算法思想,应用也是相当的广泛,包括我们后面学的数据结构尤其是树形结构里面跟递归是密不可分的。所以大家是一定要学懂它的,其实递归说起来很简单,生活中也是经常可以碰到这个场景。

        比如我们在某窗口排队人太多了,我不知道我排在第几个,那么我就问我前面的人排第几个, 因为知道他排第几我就知道我是第几了。但前面的人也不知道自己排第几那怎么办呢?他也可以继续往前面问,直到问到第一个人,然后从第一个人一直传到我这里 我就很清楚的知道我是第几了。以上这个场景就是一个典型的递归。

        我们在这个过程中大家有没有发现一个规律那么就是会有一个问的过程,问到第一个后有一个回来的过程吧。这就是递(问)加归(回)。那么这个过程我们是不是可以用一个数学公式来求解呢?那这个数学公式又是什么? f(n)=f(n-1)+1

f(n):表示我的位置

f(n-1):表示我前面的那个人;

自己调用自己;

时间空间复杂度为O(n)

         最简单的递归实现

                递归,回溯; 递归的关键相信大家已经知道了就是要求出这个递归公式,找到终止条件。现在我们可以回到课堂前跟大家讲的那个斐波那契数列数列: 1 1 2 3 5 8 13

这个的数列我们称之为斐波那契数列

        他的求解公式:f(n)=f(n-1)+f(n-2)

        终止条件:n<=2  f(n)=1

          

public class Fibonacci {


	// 1 1 2 3 5 8 13
	// f(n)=f(n-1)+f(n-2)
	public static int fab(int n) { // 分析一段代码好坏,有两个指标,时间复杂度和空间复杂度 都是:O(2^n)
		if (n <= 2)
			return 1; // 递归的终止条件
		return fab(n - 1) + fab(n - 2); // 继续递归的过程
	}

	

}

        如下图:每次递归是都是2^n次方,所以时间空间复杂度都是O(2^n)

        如何优化递归?

(1)使用非递归。所有的递归代码理论上是一定可以转换成非递归的。简单点就是for循环

(2)加入缓存:把我们中间的运算结果保存起来,这样就可以把递归降至为o(n)

(3)尾递归:什么是尾递归?尾递归就是调用函数一定出现在末尾,没有任何其他的操作了。

因为我们编译器在编译代码时,如果发现函数末尾已经没有操作了,这时候就不会创建新的栈,而且覆盖到前面去。 倒着算,不需要在回溯了,因为我们每次会把中间结果带下去。

package algorithm.rec;

public class Fibonacci {

	private static int data[]; // 初始换全部是0

	// 1 1 2 3 5 8 13
	// f(n)=f(n-1)+f(n-2)
	public static int fab(int n) { // 分析一段代码好坏,有两个指标,时间复杂度和空间复杂度 都是:O(2^n)
		if (n <= 2)
			return 1; // 递归的终止条件
		return fab(n - 1) + fab(n - 2); // 继续递归的过程
	}

	public static int fac(int n) { // 求N的阶乘 用普通递归怎么写 5=5*4*3*2*1=> f(n) =
		if (n <= 1)
			return 1;
		return n * fac(n - 1);
	}

	public static int noFab(int n) { // 不用递归 O(n)
		// 循环
		if (n <= 2)
			return 1;
		int a = 1;
		int b = 1;
		int c = 0;
		for (int i = 3; i <= n; i++) {
			c = a + b;
			a = b;
			b = c;
		}
		return c;
	}

	public static int fab2(int n) { // 用数组来做缓存 将为了O(n),空间也降至为O(n)
		if (n <= 2)
			return 1; // 递归的终止条件
		if (data[n] > 0) {
			return data[n];
		}
		int res = fab2(n - 1) + fab2(n - 2); // 继续递归的过程
		data[n] = res;
		return res;
	}
	
	public static int tailfab(int pre,int res,int n) { // 分析一段代码好坏,有两个指标,时间复杂度和空间复杂度 都是: O(n)
		if (n <= 2)
			return res; // 递归的终止条件
		return tailfab(res, pre + res, n - 1);		//JDK源码
		//参数:
		/**
		 * n 是肯定有的
		 * res 上一次运算出来结果
		 * pre 上上一次运算出来的结果
		 */
	}
	
	public static int tailFac(int n, int res) { // 尾递归 传结果,res就是我们每次保存的结果
		System.out.println(n + ":" + res);	// 这个地方打印出来的值是怎么样的?
		if (n <= 1)
			return res;
		return tailFac(n - 1, n * res);	//倒着算
	}
	
	

	
	public static void main(String[] args) {
		for (int i = 1; i <= 45; i++) {
			long start = System.currentTimeMillis();
			System.out.println(i + ":" + tailfab(1,1,i) + " 所花费的时间为"
					+ (System.currentTimeMillis() - start) + "ms");
		}
		//tailFac(5, 1);
		
		/*
		 * for (int i = 1; i <= 45; i++) { long start =
		 * System.currentTimeMillis(); System.out.println(i + ":" + fab(i) +
		 * " 所花费的时间为" + (System.currentTimeMillis() - start) + "ms"); }
		 */

		/*for (int i = 1; i <= 45; i++) {
			long start = System.currentTimeMillis();
			System.out.println(i + ":" + noFab(i) + " 所花费的时间为"
					+ (System.currentTimeMillis() - start) + "ms");
		}
		System.out.println("==================================");
		System.out.println("加了缓存的情况");
		for (int i = 1; i <= 45; i++) {
			data = new int[46];
			long start = System.currentTimeMillis();
			System.out.println(i + ":" + fab2(i) + " 所花费的时间为"
					+ (System.currentTimeMillis() - start) + "ms");
		}*/
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/954739.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据通信——传输层TCP(可靠传输机制的滑动窗口)

引言 之前提到过拥塞问题&#xff0c;如果大量数据疯狂涌入&#xff0c;接收端无法及时处理就会导致数据丢包&#xff0c;从而使得通信受到干扰。之前的连续ARQ如果不加以节制&#xff0c;疯狂发送报文&#xff0c;接收端无法及时返回ACK就会导致网络瘫痪。 滑动窗口机制协议 这…

Linux服务器部署JavaWeb后端项目

适用于&#xff1a;MVVM前后台分离开发、部署、域名配置 前端&#xff1a;Vue 后端&#xff1a;Spring Boot 这篇文章只讲后端部署&#xff0c;前端部署戳这里 目录 Step1&#xff1a;服务器上搭建后端所需环境1、更新服务器软件包2、安装JDK83、安装MySQL4、登录MySQL5、修…

一百六十六、MySQL——systemctl stop mysqld无法停止MySQL8.0服务

一、目的 为了解决MySQL的中文乱码问题&#xff0c;需要对/etc/my.cnf文件进行参数配置。 而对/etc/my.cnf文件进行配置参数之前&#xff0c;需要先停止MySQL服务 二、错误命令语句示范 &#xff08;一&#xff09;错误的命令语句 # systemctl stop mysqld &#xff08;…

SQL分组后取topN

准备数据 create table SC( SId varchar(10) comment "学生ID", CId varchar(10) comment "课程ID", score decimal(18,1) comment "课程成绩");insert into SC values(01 , 01 , 80); insert into SC values(01 , 02 , 90); insert into SC va…

用最少数量的箭引爆气球【贪心算法】

用最少数量的箭引爆气球 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同点 完全垂直 地…

Debian12 Gnome环境下的办公软件安装

一、禁用Wayland&#xff0c;启用xorg 当前Debian12 默认采用Wayland来支持gnome环境&#xff0c;但是许多软件无法在该系统下显示&#xff0c;例如&#xff1a;openoffice&#xff0c;yozo-office&#xff0c;weixin&#xff0c;fcitx。所以要在gdm3的配置文件中&#xff0c;…

港交所MMDH行情协议

目录 一、交易时间 二、MMDH与OMD的差异 三、MMDH消息类型 四、MMDH的市场快照数据 内地市场数据枢纽-证券市场(OMD-MMDH) 港交所OMD-C对接笔记 - skylerjiang - 博客园 (cnblogs.com) 一、交易时间 图 1 港交所交易时间段 图 2 消息序列 二、MMDH与OMD的差异 图 3 标准…

Leetcode213 打劫家舍2

思路&#xff1a;既然头尾不能同时取&#xff0c;那就分别算只取头或者只取尾&#xff0c;不考虑特殊情况的话是一个简单的动态规划 class Solution:def rob(self, nums: list[int]) -> int:if len(nums) < 3:return max(nums)max_sum [nums[0], max(nums[1], nums[0])…

IC芯片老化测试以及方案详解

芯片老化试验是一种对芯片进行长时间运行和负载测试的方法&#xff0c;以模拟芯片在实际使用中的老化情况。 1. 目的&#xff1a;芯片老化试验的目的是评估芯片在长时间使用和负载情况下的可靠性和性能稳定性&#xff0c;以确定其寿命和可靠性指标。 2. 测试方案设计&#xff1…

软件测试/测试开发丨Python 内置库 正则表达式

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/27058 python 内置库 正则表达式 目录 正则表达式使用re模块实现正则表达式操作 正则表达式 正则表达式就是记录文本规则的代码可以查找操作符合某些复…

大屏开发,浏览器的可视区域和设备的分辨率

在线屏幕检测 - 显示器检测 - 显示器坏点检测工具

趣解装饰者模式之《我想吃煎饼果子了》

〇、小故事 话说最近早起没时间做早饭&#xff0c;并且早上上班的地铁口不远处就有一处非常火爆的煎饼摊&#xff0c;所以我就经常去那边吃煎饼&#xff0c;一个“基础版”煎饼是7块钱&#xff0c;向煎饼中加一颗鸡蛋是1元钱&#xff0c;加一根火腿肠是3元钱&#xff0c;加鸡柳…

【算法日志】动态规划刷题:不相邻选择类问题(day40)

算法随想录刷题60Day 目录 前言 打家劫舍1 (数组) 打家劫舍2&#xff08;环形数组&#xff09; 打家劫舍3&#xff08;二叉树&#xff09; 前言 今天主要讨论不相邻选择类问题&#xff0c;会在不同数据结构题型的下探讨该类问题的解法。 打家劫舍1 (数组) 本题只需要讨论当…

微信开发之朋友圈自动评论的技术实现

简要描述&#xff1a; 朋友圈评论 请求URL&#xff1a; http://域名地址/snsComment 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明wI…

炒股10倍杠杆软件是什么?出现账户安全问题怎么办?有三个方法解决

炒股10倍杠杆软件是指一种用于股票交易的杠杆交易软件&#xff0c;可以将投资者的交易资金进行多倍放大&#xff0c;以获得更高的投资回报。然而&#xff0c;使用杠杆交易软件也伴随着一些账户安全问题&#xff0c;因此&#xff0c;本文将介绍三个方法来解决这些问题。 一、加…

C语言面试题-指针

#include <stdio.h> int main() {char str1[] "hello bit.";//地址不同char str2[] "hello bit.";const char* str3 "hello bit.";//常量是不可以被修改的const char* str4 "hello bit.";//常量是不可以被修改的if (str1 s…

臻图信息以数字孪生技术推动智慧小区数字化建设

伴随着智慧城市建设进程的加速发展&#xff0c;加速传统小区的管理与服务向智能化升级转型。运用智慧化的管理和服务&#xff0c;利用信息技术和物联网等技术手段&#xff0c;将传统的居住区域与智能设备相结合&#xff0c;实现楼宇、社区设施、服务管理的数字化、网络化、智能…

为什么中国软件需要国产化?

国产化是指技术引进项目投产后所生产的产品中&#xff0c;国内生产件的数量占整件产品生产件数量。换句话说&#xff0c;软件国产化的占比&#xff0c;直接影响到技术是否会在某一个时点上被”卡脖子“。 随着国家经济的发展和技术水平的提高&#xff0c;国家整体实力大大增强…

产品展示视频制作的要点

制作产品展示视频时通过精心策划的视频剧本和拍摄手法&#xff0c;可以准确地呈现活动的目的、主题和特点&#xff0c;让观众更好地理解和认同活动的意义。深圳产品活动视频制作公司老友记小编还为您整理了以下一些重要的制作要点&#xff1a; 1.明确目标受众&#xff1a;了解你…

博睿数据当选粤港澳大湾区金融创新研究院理事会单位,助力金融科技创新发展

近日&#xff0c;博睿数据当选粤港澳大湾区金融创新研究院理事会单位。这是对博睿数据在金融科技领域所取得成绩的高度认可&#xff0c;也是对其创新能力和发展潜力的充分肯定。 粤港澳大湾区金融创新研究院由粤港澳三地金融行业、高等院校高层和专家学者共同发起&#xff0c;经…