蓝桥杯——加深递归与循环的理解

蓝桥杯学习——递归与循环

递归与循环的区别

递归,说白了就是自己调用自己,利用的是栈后进先出的原理。理论上,任何的循环都可以重写为递归形式,所有的递归也可以被表述成循环的形式

循环改递归的两大要点

  • 发现逻辑循环中的**“相似性”**
  • 找到递归的**“出口”**
  • 确定递归的参数

踢皮球思想理解递归

“踢皮球”-常用来形容政府职能部门职责不清,相互推诿,比如你要到部门A盖个章,A叫你先去部门B盖章,B叫你去部门C盖章…这种将工作以踢皮球的方式甩给其他人做的方式其实很适用于递归。但在递归中,如果你甩给其他人的工作和分配给你的工作完全一样,则程序陷入死循环,一直没有人进行工作,一直在甩锅,因此,递归中为:**自己做一小部分事情,剩下的事情再甩给其他人去做。**即上级做玩自己的工作然后交给下级去做。

递归调用

  • 递归调用仅仅是被调用函数恰为主调函数(自己调用自己)
  • 注意每次调用的层次不同
  • 注意每次分配形参并非同一个变量
  • 注意返回的次序

练习

试题 基础练习 01字串

问题描述

对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:

00000

00001

00010

00011

00100

请按从小到大的顺序输出这32种01串。

输入格式

本试题没有输入。

输出格式

输出32行,按从小到大的顺序每行一个长度为5的01串。

样例输出

00000
00001
00010
00011
<以下部分省略>

循环解决

思路:暴力枚举

public class Main {    
	public static void main(String[] args) {
		for(int i=0;i<=1;i++){
			for(int j=0;j<=1;j++){
				for(int k=0;k<=1;k++){
					for(int l=0;l<=1;l++){
						for(int m=0;m<=1;m++){
							System.out.print(i);
							System.out.print(j);
							System.out.print(k);
							System.out.print(l);
							System.out.println(m);//注意前面的都是print,最后一个用println							
						}
					}
				}
			}
		}
	}
}

递归解决

思路:初始化目标字符串为空,长度为0,每次递归执行增加一个字符0和1两种情况,当字符长度达到5时结束递归

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
public class Main {
	static ArrayList<String>conArrayList=new ArrayList<>();
	public static void f(String s,int k) {
		if(k==5) {
		conArrayList.add(s);
		}
		else {
			f(s+'0', k+1);
			f(s+'1', k+1);
		}
		
	}
	public static void main(String[] args) {
		f("",0);
		for(String s:conArrayList) {
			System.out.println(s);
		}
		
	}

}

学习参考

https://www.bilibili.com/video/BV1ty4y117go?t=885&p=2

https://blog.csdn.net/Upwardflow/article/details/81561124

https://www.jianshu.com/p/ebd9e232f044

学习心得

时间和空间消耗

递归由于是函数调用自身,而函数调用时是有时间和空间的消耗的:每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址及临时变量,而且往栈里压入数据和弹出数据都需要时间。这就不难理解有些时候递归实现的效率不如循环。所以相对于循环,递归空间和时间一般占用量比较大。但是相对于循环,递归更加简洁明了。

重复的计算

递归有可能很多计算都是重复的,从而对性能带来很大的负面影响。递归实际上是把一个大问题拆成很多小问题,如果那些小问题存在相互重叠的部分,就存在重复的计算。可以采用保存吗,每次递归计算结果的方式进行优化。

调用栈溢出

除效率之外,递归还有可能引起调用栈溢出。前面提到了需要为每一次函数调用在内存栈中分配空间,而每个进程的栈的容量是有限的。当递归调用的层级太多时,就会超出栈的容量,从而导致调用栈溢出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦码城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值