首页 > 其他分享 >经典递归

经典递归

时间:2023-02-19 21:33:17浏览次数:39  
标签:__ uint64 return 递归 res fibo 经典 盘子

汉诺塔

问题描述

有三根柱子,分别名为A,B,C。

初始时,在柱子A上有n个圆盘,他们从上往下,盘子的大小是从小到大。

在移动和摆放的过程中,小盘子必须在大盘子上面

在保证规则的情况下,将柱子A上的所有盘子,移动到柱子C,移动中可以借助柱子B。

请打印出移动过程

大概过程

问题分析

递归的过程:

1、将最上面的n-1个盘子,从A借助C移动到B
2、将最下面的一个盘子,从A移动到C
3、将最上面的n-1个盘子,从B借助A移动到C

递归的结束条件:

问题规模变成盘子数为0时,因为当盘子数为0时就不需要移动了!

代码部分

def hano(n, a, b, c):
    if n > 0:
        hano(n - 1, a, c, b)
        print(f"{n}号盘子从{a}移动到{c}")
        hano(n - 1, b, a, c)


if __name__ == '__main__':
    hano(3, "A", "B", "C")



"""
1号盘子从A移动到C
2号盘子从A移动到B
1号盘子从C移动到B
3号盘子从A移动到C
1号盘子从B移动到A
2号盘子从B移动到C
1号盘子从A移动到C
"""

可以看到,一致递归到最里层才会开始打印中间那一行,所以可以将n作为序号来使用

斐波那契数列

斐波那契数列定义

这个数列从第3项开始,每一项都等于前两项之和。

例如

1,1,2,3,5,8,13,21,34,55,89...

问题

获得第40个数

递归解法

返回前两个数之和

"""
斐波那契数列
"""

def fibo(n):
    if n == 1 or n == 2:
        return 1
    return fibo(n - 1) + fibo(n - 2)


if __name__ == '__main__':
    print(fibo(40))
"""
102334155
"""

缓存解法

利用lru_cache缓存装饰器

"""
斐波那契数列
"""
from functools import lru_cache


@lru_cache
def fibo(n):
    if n == 1 or n == 2:
        return 1
    return fibo(n - 1) + fibo(n - 2)


if __name__ == '__main__':
    print(fibo(40))

go的问题

go也可以利用缓存来解决

但是go的数据类型上限是uint64类型的18446744073709551615

但是斐波那契数的第93位是12200160415121876738,94位就超了,所以超的部分就会被切掉

所以go中只能计算到93位,多了就不准了

这里就选择求尾数

package main

import (
	"fmt"
	"math"
	"time"
)

var (
	cache = make(map[uint64]uint64, 10000)
)

func fibo(n uint64) uint64 {
	if n == 1 || n == 2 {
		return 1
	}
	if value, ok := cache[n]; ok {
		return value
	}
	res := fibo(n-1) + fibo(n-2)
	// 93以内为完整的,93以上求尾数
	if n >= 93 {
		res = res % uint64(math.Pow10(18))
	}
	cache[n] = res
	return res
}

func main() {
	star := time.Now()
	fmt.Println(fibo(2000))
	fmt.Println("耗时:", time.Since(star))
}

阶乘

定义

一个正整数的阶乘factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。

问题

给出任意一个正整数n,求解其阶乘?

代码部分

"""
阶乘
"""

def jiechen(n):
    if n == 1:
        return 1
    return n * jiechen(n - 1)


if __name__ == '__main__':
    print(jiechen(20))

同样

go中超过20,就只能取部分尾数

package main

import (
	"fmt"
	"math"
)

func jiechen(n uint64) uint64 {
	if n == 1 {
		return 1
	}
	res := n * jiechen(n-1)
	if n >= 20 {
		res = res % uint64(math.Pow10(18))
	}
	return res
}

func main() {
	fmt.Println(jiechen(20))
}

标签:__,uint64,return,递归,res,fibo,经典,盘子
From: https://www.cnblogs.com/guangdelw/p/17135664.html

相关文章

  • C语言经典习题(二)
    打印7层杨辉三角形打印7层杨辉三角形图案如下:这个题我再前几天的刷题中也写过,但是很多人私信说上次写的太简陋了,那我这次就写完整。通过图,可以看出。无论它是多少层的......
  • 算法刷题-无重复字符的最长子串(哈希表、字符串)、数字 1 的个数(递归、数学)、对称二
    无重复字符的最长子串(哈希表、字符串)给定一个字符串,请你找出其中不含有重复字符的**最长子串**的长度。示例1:输入:s="abcabcbb"输出:3解释:因为无重复字符......
  • java中用递归实现树形结构
    本文以一个多级菜单的案列描述了在java中如何用递归来组装树形结构的数据。java中生成树形结构主要分为两步,(1)在源数据list中找到所有的根节点(2)递归为每一个根节......
  • 社招前端经典vue面试题(附答案)
    Vuex页面刷新数据丢失怎么解决体验可以从localStorage中获取作为状态初始值:conststore=createStore({state(){return{count:localStorage.getIt......
  • 算法随想Day17【二叉树】| 二叉树题目的递归解法总结
    总结思考:目前涉及基于二叉树的特性,进行递归的方案有如下:左右子树不相干的递归回溯,左右子树不相干的递归:用前序遍历,先处理"中"节点,判断是否达到终止条件进行相关处理(终止......
  • Java 递归和非递归实现二叉树的先序,中序,后序遍历
    前言说到树的四种遍历方式,可能大家第一时间都会想到它的四种遍历方式,并快速说了它的特点。先序(先根)遍历:即先访问根节点,再访问左孩子和右孩子中序遍历:先访问做孩子......
  • 阿里前端经典react面试题集锦
    hooks为什么不能放在条件判断里以setState为例,在react内部,每个组件(Fiber)的hooks都是以链表的形式存在memoizeState属性中update阶段,每次调用setState,链表......
  • 腾讯前端经典react面试题(附答案)
    React性能优化在哪个生命周期?它优化的原理是什么?react的父级组件的render函数重新渲染会引起子组件的render方法的重新渲染。但是,有的时候子组件的接受父组件的数据没有......
  • C语言经典习题(一)
    试验报告(一)1、本实验要求事先编好解决下面问题的程序,然后上机输入程序并调试运行程序。有如下函数:①写程序,输入x的值,输出y相应的值。用scanf函数输入x的值,求y值。②运......
  • 【LeetCode二叉树#01】二叉树的遍历(递归/迭代)
    二叉树递归遍历写递归算法时候需要遵循的三个点:确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数,并且还要明确每次递......