Java算法递归与递推

article/2025/10/29 12:24:26

Java算法----递归与递推

  • 递推实现递推思想
  • 递归实现递归思想
  • 递归实现递推思想
  • 递推实现递归思想
  • 四种方法的特点
  • 思维拓展

  • 问题:给你一个整数n,如果n是奇数,就进行运算n=n*3+1,如果n是偶数,就进行运算n=n/2,直到n等于1为止,请计数一种进行了多少次运算(使用四种编码方式实现)
  • 思维拓展:基于上面的问题,如果让你找出从1到10000中哪个数字所需要的运算次数最多,应该如何编写代码?(注:特别要注意如何便面重复运算)

递推实现递推思想

 	/*递推实现递推思想*/public static Integer getSum1(Integer n) {if (n <= 0) return 0;//越界代偿Integer sum = 0;while (true) {if (n == 1) break;if (n % 2 == 0) n = n / 2;else n = n * 3 + 1;sum++;}return sum;}

递归实现递归思想

 	 /*递归实现递归思想*/public static Integer getSum2(Integer n) {if (n <= 0) return 0;//越界代偿if (n == 1) return 0;if (n % 2 == 0) return getSum2(n / 2) + 1;else return getSum2(n * 3 + 1) + 1;}

递归实现递推思想

 	 /*递归实现递推思想*/public static void getSum3(Integer n, int sum) {if (n <= 0) return;//越界代偿if (n == 1) {System.out.println(sum);return;}if (n % 2 == 0) getSum3(n / 2, ++sum);else getSum3(n * 3 + 1, ++sum);}

递推实现递归思想

 	/*借助栈数据结构递推实现递归思想*/public static Integer getSum4(Integer n) {if (n <= 0) return 0;//越界代偿var stack = new Stack<Integer>();stack.push(n);var sum = 0;while (true) {var top = stack.peek();if (top == 1) {var size = stack.size();for (int i = 0 ;i<size-1;i++){stack.pop();sum++;}break;}else if (top % 2 == 0) stack.push(top / 2);else stack.push(top * 3 + 1);}return sum;}
}

四种方法的特点

以下总结出自刘铁猛老师的《算法之禅》

方案特点
递推实现递推思想中规中矩,使用循环语句,有时候会有队列参与
递归实现递推思想自顶向下式的递归代码,可使代码得到简化
递归实现递归思想顺利成章,方法调用自己,自底向上,结果对其
递推实现递归思想使用循环语句加栈数据结构,避免了调用栈的溢出

思维拓展

通过一个while从1到n去执行getSum1获得运算次数
并在运算过程中将其每次运算的结构放入一个队列(Queue)中
并将最终运算为1的结果次数,以及该数的数值存入hashmap中(key为数值,value为次数)
同时进行查重,如果有重复或者大于n的数直接Continue跳过

  	/*运算过程中将其每次运算的结构放入一个队列(Queue)中*/public static Integer getSum1(Integer n, LinkedList<Integer> numQ) {if (n <= 0) return 0;//越界代偿Integer sum = 0;while (true) {if (n == 1) break;if (n % 2 == 0) {n = n / 2;numQ.offer(n);} else {n = n * 3 + 1;numQ.offer(n);}sum++;}return sum;}
  	/*通过一个while从1到n去执行getSum1获得运算次数并在运算过程中将其每次运算的结构放入一个队列(Queue)中并将最终运算为1的结果次数,以及该数的数值存入hashmap中(key为数值,value为次数)同时进行查重,如果有重复或者大于n的数直接Continue跳过*/public static Map<Integer, Integer> getMaxSum(int n) {var sums = new HashMap<Integer, Integer>();var numQ = new LinkedList<Integer>();int i = 1;while (true) {if (i > n) break;if (numQ.contains(i)) {i++;continue;}var sum = getSum1(i, numQ);sums.put(i, sum);i++;}for (var num : numQ) {if (sums.containsKey(num) || num > n) continue;sums.put(num, getSum1(num));}return sums;}

此时可以通过loadMap()来查看刚创建的hashmap

    /*打印输出hashmap*/public static void loadMap(Map<Integer, Integer> map) {Iterator iter = map.entrySet().iterator();while (iter.hasNext()) {Map.Entry entry = (Map.Entry) iter.next();Object key = entry.getKey();Object val = entry.getValue();System.out.printf("key=%d,val=%d\n", key, val);}}
public class Main {public static void main(String[] args) {long a= System.currentTimeMillis();//获取当前系统时间(毫秒)var sums= Homework.getMaxSum(10000);Homework.loadMap(sums);System.out.print("程序执行时间为:");System.out.println(System.currentTimeMillis()-a+"毫秒");}}

输出结果如下所示:
在这里插入图片描述
此时可以通过hashmap的键值对来查询1-10000的计算所需要的次数
再通过Map.Entry的排序,即可获取最大运算次数的数字

 	/*将hashmap中的value进行排序并打印输出*/public static void mapSort(Map<Integer, Integer> sums) {List<Map.Entry<Integer, Integer>> sumList = new ArrayList<>();for (var entry : sums.entrySet())sumList.add(entry);sumList.sort(new Comparator<Map.Entry<Integer, Integer>>() {@Overridepublic int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {return o2.getValue() - o1.getValue();}});for(Map.Entry<Integer, Integer> entry: sumList){System.out.printf("key=%d,val=%d\n", entry.getKey(), entry.getValue());}}
public class Main {public static void main(String[] args) {long a= System.currentTimeMillis();//获取当前系统时间(毫秒)var sums= Homework.getMaxSum(10000);Homework.mapSort(sums);System.out.print("程序执行时间为:");System.out.println(System.currentTimeMillis()-a+"毫秒");}}

这样即可输出最大次数的数字6171,如下所示
在这里插入图片描述
如有错误,希望大家能够指出,我将加以改正


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

相关文章

Java开发 | 数据结构和算法之——递归算法

著名的Pascal之父——Nicklaus Wirth(沃斯)让他获得图灵奖的一句话就是他提出的著名公式:“程序=数据结构+算法”,这个公式对计算机科学的影响类似于爱因斯坦的质能方程在物理界的影响。 因此可以看出来数据结构和算法在我们开发程序中有多么的重要了,下面我们来简单认识…

java中递归算法的理解

Coding多了&#xff0c;递归算法是非常常见的&#xff0c;最近我一直在做树形结构的封装&#xff0c;所以更加的离不开递归算法。所以今天就简单说一下这个递归算法&#xff0c;用java实现一个非常经典的递归实例。 递归算法&#xff0c;其实说白了&#xff0c;就是程序的自身调…

【递归】java递归算法及替代方法

文章目录 菜单树递归&#xff08;树根往子节点递归&#xff09;需求&#xff1a; 取所有level小于2的节点 ( 返回结果为普通list格式) 为list格式的数据设置children&#xff08;非递归&#xff09;需求&#xff1a; 数据库查出来的原始list 如果有children就设置 使用循环代替…

Java递归

1.递归的概念&#xff1a; 一个方法在执行过程中调用自身, 就称为 "递归". 示例&#xff1a; //递归求n的阶乘 public static void main(String[] args) {int n 5;int ret factor(n);System.out.println("ret " ret); }public static int factor(int…

java递归算法(一)——详解以及几个经典示例

什么是递归 递归就是一个程序或函数在其中定义或说明有之间或者间接调用自身的一种方法&#xff0c;它通常把一个大型复杂的问题层层转化为一个原问题相似的规模较小的问题来求解&#xff0c;递归策略只需要少量的程序就可以描述出解题过程所需要的多次重复计算&#xff0c;大…

Java 递归算法

一、概述&#xff1a; Java递归&#xff1a;简单说就是函数自身直接或间接调用函数的本身。 二、应用场景&#xff1a; 若&#xff1a;一个功能在被重复使用&#xff0c;并每次使用时&#xff0c;参与运算的结果和上一次调用有关&#xff0c;这时就可以使用递归来解决这个问题…

递归与递归算法实例(java实现)

一、递归介绍 递归算法&#xff08;英语&#xff1a;recursion algorithm&#xff09;在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。绝大 多数编程语言支持函数的自调用&#xff0c;在这些语言中函数可以通过调用自身来进行递归。 定义&#xff1…

Java的递归算法

递归算法设计的基本思想是&#xff1a;对于一个复杂的问题&#xff0c;把原问题分解为若干个相对简单类同的子问题&#xff0c;继续下去直到子问题简单到能够直接求解&#xff0c;也就是说到了递推的出口&#xff0c;这样原问题就有递推得解。 关键要抓住的是&#xff1a; &…

java递归算法实现

Coding多了&#xff0c;递归算法是非常常见的&#xff0c;最近我一直在做树形结构的封装&#xff0c;所以更加的离不开递归算法。所以今天就简单说一下这个递归算法&#xff0c;用java实现一个非常经典的递归实例。 递归算法&#xff0c;其实说白了&#xff0c;就是程序的自身调…

【Java】递归算法

文章目录 什么是递归&#xff1f;递归求阶乘递归求解斐波那契数列猴子吃桃问题 什么是递归&#xff1f; 程序 调用自身 的编程技巧成为 递归&#xff08;recursion&#xff09;。 递归算法是一种直接或间接调用、定义自身的函数或方法的算法&#xff0c;也就是调用自身。 递归…

Java递归算法

递归在程序语言中就是方法本身自己调用自己&#xff0c;而递归思想是算法的重要思想之一&#xff0c;就是利用递归来实现解决问题的算法。 递归也分为直接递归和间接递归。 那么什么叫直接递归什么又叫间接递归呢&#xff1f; //直接递归调用 function(){...function();... …

散布矩阵(scatter_matrix)及相关系数(correlation coefficients)实例分析

在进行机器学习建模之前&#xff0c;需要对数据进行分析&#xff0c;判断各特征(属性&#xff0c;维度)的数据分布及其之间的关系成为十分必要的环节&#xff0c;本文利用Pandas和Numpy的散布矩阵函数及相关系数函数对数据集特征及其关系进行实例分析。 散布矩阵(scatter_matri…

Probability And Statistics——CorrelationsCovariance

Skew&#xff08;偏度&#xff09; 在概率论和统计学中&#xff0c;偏度衡量实数随机变量概率分布的不对称性。偏度的值可以为正&#xff0c;可以为负或者甚至是无法定义。在数量上&#xff0c;偏度为负&#xff08;负偏态&#xff09;就意味着在概率密度函数左侧的尾部比右侧的…

structural covariance network

structural covariance network 结构协方差网络 结构协方差网络是一个较老的概念&#xff0c;只是近年受到了一定的重视。 大佬 Aaron Alexander-Bloch 在2013年通过一篇综述描述了这种结构协方差网络的应用意义及前景。 既往一般是在bold信号和fiber tracking建立连接&#xf…

_variant_t、CComVariant与COleVariant、CDBVariant

目前计算机语言多种多样&#xff0c;如C、Java、Basic、Pascal等&#xff0c;此外还有JavaScript、VBScript、ActionScript等脚本语言&#xff0c;它们各自维护自己的数据类型&#xff0c;当使用C这样强类型的语言来读取数据库或者与其他语言之间来交换数据时&#xff0c;它很有…

Partial correlation coefficient

利用PYTHON计算偏相关系数&#xff08;Partial correlation coefficient) 在统计学中&#xff0c;我们经常使用皮尔逊相关系数来衡量两个变量之间的线性关系。然而&#xff0c;有时我们感兴趣的是理解两个变量之间的关系&#xff0c;同时控制第三个变量。 例如&#xff0c;假设…

Multilevel Cooperative Coevolution for Large Scale Optimization

0、论文背景 本文在CCEA_G的基础上&#xff0c;提出了MLCC框架。在MLCC中&#xff0c;基于不同组大小的随机分组策略构造了一组问题分解器。演化过程分为若干个循环&#xff0c;在每个周期开始时&#xff0c;MLCC使用自适应机制根据其历史性能选择分解器。由于不同的组大小捕获…

mean value coordinates(均值重心坐标)定义及证明

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 在图形学中对于物体的描述往往是离散&#xff0c;但是在具体展示过程中我们又希望是连续。线性插值是解决离散与连续的常用手段。 三角形中的插值点击前往凸四边形中的…

numpy中的convolve的理解

写在前面 浏览更多内容&#xff0c;可访问&#xff1a;http://www.growai.cn 欢迎您关注作者知乎&#xff1a;ML与DL成长之路 推荐关注公众号&#xff1a;AI成长社&#xff0c;ML与DL的成长圣地。 函数 numpy.convolve(a, v, mode‘full’)&#xff0c;这是numpy函数中的卷…

Clustering Coefficient

Define Clustering Coefficient&#xff1a;聚类系数 Clustering Coefficient measures the degree to which nodes in a network tend to cluster or form triangles. ——聚类系数衡量网络中节点倾向于聚类或形成三角形的程度 Triadic Closure 三元闭包 The tendency of…