简单编程题目连载(五)——找零钱
来源:互联网 发布:java框架面试题及答案 编辑:程序博客网 时间:2024/05/22 01:28
接着上一篇的经典动态规划题目来说。
上一篇的解题方法为暴力求解法,暴力求解法之所以称之为暴力求解法,是因为其中存在着大量的冗余,比如:
对于penny数组{5,10,25,1},目标金额为1000,来说,当使用0张5元,1张10元,进行接下来的递归计算,调用的函数为:res(penny,2,990)。而当使用2张5元,0张10元,进行接下来的递归计算,调用的函数为:res(penny,2,990)。
原解法中,递归计算的数组penny是不变的,每次改变的是递归函数的index和aim。而上述例子表明存在大量index和aim相同的递归函数,也就是说,进行了大量的重复计算。所以优化的第一个思路就是将这些重复计算记录下来,下次遇到之前计算过的结果,直接查找调用。这就是记忆搜索法。这是一个空间换时间的方法。
接下来看代码:
public int countType(int[] penny,int n,int aim){ if(penny == null || n <= 0 || aim <= 0){ return 0; } //声明一个二维数组 用来存重复的res(penny,index,aim);的结果 int[][] map = new int[n+1][aim+1]; res(penny,index,aim,map);}public int res(int[] penny,int index,int aim,int[][] map){ int result = 0; //说明有值且不为0 if(map[index][aim] > 0){ return map[index][aim]; }else if(map[index][aim] == -1){ return 0; }else{//这个意思就是第一次遇到这个index和aim的组合 result = aim == 0 ? 1 : 0; for(int i = 0;index < penny.length && penny[index]*i <= aim && aim > 0;i++){ result += res(penny,index+1,aim-penny[index]*i,map); } //设置一个-1的目的是为了 区分 递归结果为0 的那些结果与数组初始化结果也为零冲突 map[index][aim] = result == 0 ? -1 : result; return result; }}
以上为找零钱题目的记忆搜索法求解过程。
0 0
- 简单编程题目连载(五)——找零钱
- 简单编程题目连载(四)——找零钱
- 简单编程题目连载(六)——找零钱
- 简单编程题目连载(十五)——找二叉树中的最大搜索二叉子树
- 简单编程题目连载(一)
- 简单编程题目连载(二)
- 简单编程题目连载(三)
- 找零钱——贪心
- 找零钱问题—贪心
- 简单编程题目连载(七)——经典台阶问题
- 简单编程题目连载(八)——最短路径问题
- 简单编程题目连载(九)——最长上升子序列
- 简单编程题目连载(十)——公共最长子序列
- 简单编程题目连载(十一)——0-1背包问题
- 简单编程题目连载(十二)——最优编辑问题
- 简单编程题目连载(十三)——拓扑结构相同子树判断
- 简单编程题目连载(十四)——最长无重复字符子串
- 动态规划系列(2)——找零钱问题
- Hibernate
- HTML5 简介
- Linux下搭建redis集群(简单例子)
- 二叉树的镜像
- 真正独立
- 简单编程题目连载(五)——找零钱
- ECMAScript6 (ES6、ES2015)新特性详解
- [python] RSA加密
- 问题五十三:怎么用ray tracing画参数方程表示的曲面(1)
- UVaLive 3938 "Ray, Pass me the dishes!" (线段树求动态最大连续和)
- OpenCV--阈值分割-threshold()
- java实现DH非对称加密工具包
- 使用U盘安装ubuntu 16.04简易教程
- Unity&Shader高级篇-渲染路径(Rendering Paths)