Java版算法思想递归&分治&回溯&枚举&基础数论

Posted chenry777

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java版算法思想递归&分治&回溯&枚举&基础数论相关的知识,希望对你有一定的参考价值。

本篇涉及代码github地址: https://github.com/chenruoyu0319/data-structure-for-java/tree/main/%E9%80%92%E5%BD%92%26%E5%88%86%E6%B2%BB%26%E5%9B%9E%E6%BA%AF%26%E6%9E%9A%E4%B8%BE

一、前言

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

再比如斐波那契数列:1 1 2 3 5 8 13 21 … ,其有什么特点?从第三个数开始,就等于前面两个数相加。其中就用到了数论的思想:利用数学公式或者定理或者规律求解问题。算法思想中最难的点就是:递归+动态规划了,且递归是树论的基础:二叉树,红黑树,所以我们一定要学好递归。

二、递归的定义

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

比如我们在某窗口排队人太多了,我不知道我排在第几个,那么我就问我前面的人排第几个,

因为知道他排第几我就知道我是第几了。但前面的人也不知道自己排第几那怎么办呢?他也可以继续往前面问,直到问到第一个人,然后从第一个人一直传到我这里 我就很清楚的知道我是第几了。以上这个场景就是一个典型的递归。我们在这个过程中大家有没有发现一个规律那么就是会有一个问的过程,问到第一个后有一个回来的过程吧。这就是递(问)加归(回)。那么这个过程我们是不是可以用一个数学公式来求解呢?那这个数学公式又是什么?

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

f(n): 表示我的位置

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

事实上整个过程就是个自己调用自己的过程

三、什么样的情况下可以用递归?

(1)一个问题的解可以分解为几个子问题的解:子问题,我们通过分治的思想可以把一个数据规模大的问题,分解为很多小的问题。

我们可以把刚刚那个问前面的那个人看为子问题,也就是一个大化小的过程。

(2)这个问题与分解之后的子问题,求解思路完全一样。

(3)一定有一个最后确定的答案,即递归的终止条件:刚刚那个问题就是第一个人。第一个人是肯定知道自己排第几吧即n=1的时候,如果没有这个特性那么我们这个递归就会出现死循环,最后程序就是栈溢出:stack out of。

备注: 所有使用递归的代码一定可以改成不使用递归的方式实现 —— 循环

四、递归如何实现?里面有哪些算法思想?

详见guthub内代码

五、递归优化

(1)使用非递归。所有的递归代码理论上是一定可以转换成非递归的。

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

(3)尾递归:什么是尾递归?尾递归就是调用函数一定出现在末尾,没有任何其他的操作了。因为我们编译器在编译代码时,如果发现函数末尾已经没有操作了,这时候就不会创建新的栈,而且覆盖到前面去。其实倒着算,这样就不需要在回溯了,因为我们每次会把中间结果带下去。

以上是关于Java版算法思想递归&分治&回溯&枚举&基础数论的主要内容,如果未能解决你的问题,请参考以下文章

递归与分治思想:八皇后问题 (在此用递归) (回溯算法的典型题)

java——递归(动态规划,回溯)

算法-02 | 分治| 回溯

归并排序 && 快速排序

归并排序 && 快速排序

递归与分治思想:汉诺塔(递归 && 分治思想)