力扣2241. 设计一个 ATM 机器

力扣上的一个中等难度的题,之所以写一篇博客记录下来,是因为貌似触发了力扣的彩蛋,第一次遇见,感觉挺有意义的。

题目如下:

一个 ATM 机器,存有 5 种面值的钞票:20 ,50 ,100 ,200 和 500 美元。初始时,ATM 机是空的。用户可以用它存或者取任意数目的钱。

取款时,机器会优先取 较大 数额的钱。

    比方说,你想取 $300 ,并且机器里有 2 张 $50 的钞票,1 张 $100 的钞票和1 张 $200 的钞票,那么机器会取出 $100 和 $200 的钞票。
    但是,如果你想取 $600 ,机器里有 3 张 $200 的钞票和1 张 $500 的钞票,那么取款请求会被拒绝,因为机器会先取出 $500 的钞票,然后无法取出剩余的 $100 。注意,因为有 $500 钞票的存在,机器 不能 取 $200 的钞票。

请你实现 ATM 类:

    ATM() 初始化 ATM 对象。
    void deposit(int[] banknotesCount) 分别存入 $20 ,$50,$100,$200 和 $500 钞票的数目。
    int[] withdraw(int amount) 返回一个长度为 5 的数组,分别表示 $20 ,$50,$100 ,$200 和 $500 钞票的数目,并且更新 ATM 机里取款后钞票的剩余数量。如果无法取出指定数额的钱,请返回 [-1] (这种情况下不取出任何钞票)。

题目解析

这道题的意思是,ATM机中原有的钞票数都为0,直到我们往里面存钱之后,才会有钱。但是当我们取钱的时候,只要有大数值面额的钞票,并且我所要取的钱比这个数值面额要大,那就会先取这个数额的钞票。

举个例子:我要取600块,因为机器中存在500块的钞票,因此我不能去取200块的,只能取500块的,之后还剩下100块要取的额度,虽然存在200块,但是我现在要取的比200小,因此向下找,直接取100块的,至此完成操作。

代码解析

var ATM = function() {
    this.moneys = [0,0,0,0,0];
    this.size = [20,50,100,200,500];
};

/** 
 * @param {number[]} banknotesCount
 * @return {void}
 */
ATM.prototype.deposit = function(banknotesCount) {
    for(let i=0;i<5;i++){
        this.moneys[i]+=banknotesCount[i];
    }
};

/** 
 * @param {number} amount
 * @return {number[]}
 */
ATM.prototype.withdraw = function(amount) {
    let give = [0,0,0,0,0];
    let temp = [...this.moneys];
    let pieces,last=0;
    for(let i=4;i>=0;i--){
        pieces = Math.floor(amount/this.size[i]);
        last = amount%this.size[i];
        if(pieces>=this.moneys[i]){
            give[i] += this.moneys[i];
            last += this.size[i]*(pieces-this.moneys[i]);
            this.moneys[i] = 0
        }else{
            this.moneys[i] -= pieces;
            give[i] += pieces;
        }
        amount = last;
    }
    if(amount!==0){
        this.moneys = temp;
        return [-1]
    };
    return give;
};

原数组

为了代表钞票额度和每种额度钞票的数量,我在原函数中设置了两个数组,moneys数组用于代表每种额度钞票的数量,size数组用于代码这种钞票额度的大小。

deposit方法实现

deposit方法很容易实现,只需要一个for循环,遍历输入的数组,将新增对应额度的钞票数量加到moneys数组中对应的位置即可。

withdraw方法实现

withdraw方法,也就是取钱的方法,是这道题的核心。要求我们若是ATM机中的钞票数量足以满足取钱要求的话,就返回一个数组,数组代表要取出的每种钞票的数量。否则返回[-1]。

因此我设置了一个全零数组give,代表要取出的钞票数组,还用一个数组对moneys进行了深复制,供我们在不满足取钱要求的时候,可以将moneys恢复原形。为了更好的计算对每种钞票数量的要求,我设置了两个变量pieces、last,代表对当前钞票数量的需求和剩下要取钱的额度。

之后就开始for循环遍历了,先用要取的钱除以当前面值,代表尽可能取当前面值的钞票,要是当前面值的钞票数量不足以供应时,则将剩下那部分加上之前取余的数值,成为接下来要取的额度。

运行结果

应该是这道题比较冷门,写的人比较少,并且这一刻我电脑慢了许久的网速突然间快了起来,最后刷新了这道题js算法的执行用时,值得纪念一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值