Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >javascript经典算法之最小硬币找零问题

javascript经典算法之最小硬币找零问题

作者头像
徐小夕
发布于 2020-05-08 09:59:10
发布于 2020-05-08 09:59:10
1.6K01
代码可运行
举报
文章被收录于专栏:趣谈前端趣谈前端
运行总次数:1
代码可运行

前言

笔者之前也断断续续写过几篇javascript数据结构和算法的文章,之所以要写,是因为它们很重要。在前端的职业生涯中我们会遇到很多选择,走向不同的方向,但是唯一不变的,就是技术思维。

而算法,正是技术思维应用的结晶。对于初中级工程师,实现业务是我们的首要职责,没有太多的时间和精力关注代码性能和执行效率,往往能用即可。这种状态无非对错,毕竟在不同阶段侧重点不同,业务能力往往是一个工程师进阶的必经之路,但是往长远来看,维持这种状态非常不利于自身的长远发展,因为长期处于业务优先的状态容易让人产生思维惰性,不愿意尝试更优方案,所以最后的结果就是忙了很多年,能力却没有提升多少,最终会被新生代淘汰。

笔者在刚从事前端工作的时候也认为算法对于前端,意义不大。天真的以为前端就是写写页面,调调接口,没有任何难度。但是越往后研究,随着公司对用户体验的要求越来越高,以及对前端业务逻辑的日渐复杂,之前的"算法无用论"不断受到了挑战,最后为了改变已有的格局,笔者慢慢开始研究设计模式和算法,刚开始可能比较吃力,但是坚持下去,不断的理解和应用,大大提高了笔者解决问题的能力,并且也逐渐挑起了公司前端的大梁.。所以作为一个过来人,笔者希望大家也逐渐对算法这块重视起来,毕竟如果想进大厂或者自己心仪的公司,学习算法是你的必经之路。

正文

笔者抽空总结了几个比较经典且实用的算法, 最少硬币找零问题 是本文介绍的第一道算法题:

问题:给出要找零的钱数amount以及可用的硬币面额c1, c2, c3, ..., 求所需的最少硬币个数。

思考这道问题可以有很多不同的思路, 笔者主要采用两种方法来解决这个问题:

1. 动态规划法 2. 贪心算法 接下来笔者具体介绍这两种算法的思路和实现代码.

1. 动态规划法

动态规划的思想是把一个复杂问题分解为多个子问题,通过解决一个个子问题,再把子问题合并比较,从而解决复杂问题的思想。

硬币找零问题也可以用该思想来解决,首先按照正常的逻辑,我们可以先计算在给定金额amount给定面额下,一共有几种找零方法,然后求出长度最短的找零方案。当我们使用动态规划来解决该问题时,我们可以将其分解成几个子方案,最终通过条件判断最优方案,具体实现代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 硬币找零算法
function MinCoinChange(coins) {
  let cache = {}

  this.makeChange = function(amount) {
    let me = this;
    if(!amount) {
      return []
    }
    if(cache[amount]) {
      return cache[amount]
    }
    let min = [], newMin, newAmount;
    for(let i=0, len = coins.length; i<len; i++){
      let coin = coins[i];
      newAmount = amount - coin;
      if(newAmount >= 0) {
        newMin = me.makeChange(newAmount);
      }
      if(newAmount >= 0 && (newMin.length < min.length - 1 || !min.length) && (newMin.length || !newAmount)) {
        min = [coin].concat(newMin);
      }
    }
    return (cache[amount] = min)
  }
}

2. 贪心算法

贪心算法的基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一步都要确保能获得局部最优解。每一步只考虑一个数据,他的选取应该满足局部优化的条件。若下一个数据和部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加算法停止。

其本质是一种近似解法,通过局部最优解来实现整体最优的目的,应用到我们的题目中,好比如下图所示的思路:

局部最优意味着每次我们都优先取最大的硬币面额,直到剩余金额不足最大金额时,我们会取第二大的面额,以此类推,从而实现总硬币数最小的目的。其思想非常简单,我们直接上代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 最少硬币找零 - 贪心算法
function MinCoinChange1(coins) {
  return function(amount) {
    let total = 0, change = []
    for(let i= coins.length; i>=0; i--) {
      let coin = coins[i]
      while(total + coin <= amount) {
        change.push(coin)
        total += coin
      }
    }
    return change
  }
}

以上就是两种算法的实现,大家也可以想想其他的解决方案,欢迎一起交流讨论。

最后

为了巩固算法知识,笔者定了一个2个月的小目标, 2个月里每周总结一道算法题及其解法, 希望以此来提高自己以及大家在实际工作中的算法应用.

同时笔者每周会总结1-2篇企业中实用的工程化技术总结, 内容包括小程序, H5开发, 数据可视化,前端工程化/组件化等实战知识,如果疑问,欢迎和笔者交流~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 趣谈前端 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
浅析常见的算法范式
分而治之是一种常见的算法设计,它的思路是把问题分解为与原始问题相似的较小子问题。通常以递归方式解决子问题,并结合子问题的解决方案来解决原始问题。
疯狂的技术宅
2020/09/29
9770
浅析常见的算法范式
js算法初窥05(算法模式02-动态规划与贪心算法)
  在前面的文章中(js算法初窥02(排序算法02-归并、快速以及堆排)我们学习了如何用分治法来实现归并排序,那么动态规划跟分治法有点类似,但是分治法是把问题分解成互相独立的子问题,最后组合它们的结果,而动态规划则是把问题分解成互相依赖的子问题。   那么我还有一个疑问,前面讲了递归,那么递归呢?分治法和动态规划像是一种手段或者方法,而递归则是具体的做操作的工具或执行者。无论是分治法还是动态规划或者其他什么有趣的方法,都可以使用递归这种工具来“执行”代码。   用动态规划来解决问题主要分为三个步骤:1、定义
zaking
2018/07/04
1.1K0
【愚公系列】2023年12月 五大常用算法(四)-贪心算法
贪心算法(Greedy Algorithm)的基本思想是,在每一步中都选择局部最优的解,最终得到全局最优解。也就是说,贪心算法是在一定的约束条件下,逐步地构建问题的解,通过每一步选择局部最优的策略来达到全局最优的解。贪心算法的求解过程非常高效,但有时可能会得到次优解或者无解。因此,在应用贪心算法时,需要注意问题的约束条件和性质,以及选取合适的贪心策略。
愚公搬代码
2023/12/15
3000
Python高级算法——贪心算法(Greedy Algorithm)
贪心算法是一种优化问题的解决方法,它每步选择当前状态下的最优解,最终希望通过局部最优的选择得到全局最优解。在本文中,我们将深入讲解Python中的贪心算法,包括基本概念、算法思想、具体应用场景,并使用代码示例演示贪心算法在实际问题中的应用。
Echo_Wish
2023/12/11
1.3K0
dp 类找零钱类问题
这类问题,需要维护,之前的状态,当前的状态是 (当前 - 当前值) 的上一个状态的最值相关
Tim在路上
2020/08/04
4920
LeetCode-322-零钱兑换
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
benym
2022/07/14
5350
LeetCode-322-零钱兑换
钞票找零-贪心,动态规划算法
钞票找零问题是一个非常古老的问题,百度那些都有,本文将一步步的讲解关于钞票找零的算法以及优化过程.
仙士可
2019/12/18
9430
动态规划应用--找零钱
找零问题,在贪心算法讲过。但是贪心不一定能得出最优解。假设有几种不同币值的硬币v1,v2,.……vn(单位是元)。如果要支付w元,求最少需要多少个硬币。比如,有3种不同的硬币,1元、3元、5元,我们要支付9元,最少需要3个硬币(3个3元的硬币)。
Michael阿明
2021/02/20
7070
动态规划应用--找零钱
TypeScript 实战算法系列(十):实现动态规划
前面的一系列文章跟大家分享了各种数据结构和算法的实现,本文将分享一些算法的设计技巧:分而治之、动态规划,使用这些技巧可以借算法来解决问题,提升自己解决问题的能力,欢迎各位感兴趣的开发者阅读本文。
一只图雀
2020/09/10
9320
JS面试之数据结构与算法 (5)
JS面试之函数(1) JS面试之对象(2) JS面试之数组的几个不low操作(3) JS面试之http0.9~3.0对比分析(4)
火狼1
2019/04/17
1K0
JS面试之数据结构与算法 (5)
硬币找零问题
顾名思义,就是你去商店买完东西,售货员会给你用若干枚硬币找钱,如何使用这些硬币完成找零。
你的益达
2020/08/05
1.5K0
找零问题与动态规划
后来我发现在 leet code 也有类似的题,是个找零问题,就是不同面值的硬币组合成一个数有多少种情况。还挺有意思的,我就做了一下,用了递归:
Sheepy
2018/12/06
9040
经典算法之贪心算法
  贪心算法,又称贪婪算法(Greedy Algorithm),是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优解出发来考虑,它所做出的仅是在某种意义上的局部最优解。  
用户3467126
2019/11/08
1.7K0
算法:贪心策略到动态规划
贪心策略概念就是:每一步都采取当前状态下最优的选择(局部最优解),从而希望推导出全局最优解。
Wu_Candy
2022/07/04
4250
算法系列之贪心算法
在算法中,贪心算法(Greedy Algorithm)是一种常见的解决优化问题的算法。贪心算法的核心思想是:在每一步选择中都采取当前状态下最优的选择,即贪心的做出局部最优的决策,从而希望最终能够得到全局最优解。尽管贪心算法并不总是能够得到全局最优解,但在许多实际问题中,它能够提供足够好的解决方案,并且具有较高的计算效率。
修己xj
2025/03/12
1530
算法系列之贪心算法
每日手撕一道算法题-322.零钱兑换
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
编程之心
2020/08/13
7730
每日手撕一道算法题-322.零钱兑换
用javascript分类刷leetcode3.动态规划(图文视频讲解)
动态规划,英文:Dynamic Programming,简称DP,将问题分解为互相重叠的子问题,通过反复求解子问题来解决原问题就是动态规划,如果某一问题有很多重叠子问题,使用动态规划来解是比较有效的。
hellocoder2028
2022/11/14
5520
力扣322——零钱兑换
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
健程之道
2020/02/19
4080
一文说清动态规划
动态规划(dynamic programming,简称 dp)是工程中非常重要的解决问题的思想,从我们在工程中地图软件上应用的最短路径问题,再在生活中的在淘宝上如何凑单以便利用满减券来最大程度地达到我们合理薅羊毛的目的 ,很多时候都能看到它的身影。不过动态规划对初学者来说确实比较难,dp状态,状态转移方程让人摸不着头脑,网上很多人也反馈不太好学。其实任何算法的学习都是有它的规律和套路的,只要掌握好它的规律及解题的套路,再加上大量的习题练习,相信掌握它不是什么难事。本文将会用比较浅显易懂地讲解来帮助大家掌握动态规划这一在工程中非常重要的思想,相信看完后,动态规划的解题套路一定能手到擒来(文章有点长,建议先收藏再看,看完后一定会对动态规划的认知上升到一个台阶!)
Crossin先生
2020/02/25
8110
【算法统治世界】动态规划 个人笔记总结
动态规划可以被视为一种有限状态自动机,其中每个状态代表了问题的一个子集,状态之间的转移代表了子问题之间的关联。在有向无环图(Directed Acyclic Graph,简称DAG)中,每个节点代表一个状态,而边则代表了状态之间的转移关系。通过这种方式,动态规划将问题转化为在一个DAG上寻找最优路径的问题。
苏泽
2024/04/10
1320
【算法统治世界】动态规划 个人笔记总结
相关推荐
浅析常见的算法范式
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验