每周一题:拿硬币(更新JS)

题目:

桌上有 n 堆力扣币,每堆的数量保存在数组 coins 中。我们每次可以选择任意一堆,拿走其中的一枚或者两枚,求拿完所有力扣币的最少次数。

示例 1:

输入:[4,2,1]

输出:4

解释:第一堆力扣币最少需要拿 2 次,第二堆最少需要拿 1 次,第三堆最少需要拿 1 次,总共 4 次即可拿完。

示例 2:

输入:[2,3,10]

输出:8

限制:

1 <= n <= 4
1 <= coins[i] <= 10

 

代码:

var minCount = function(coins) {
    let numbers=0,result=0;
    for(let i=0;i<coins.length;i++){
        if(coins[i]==1){
            numbers=1;
        }else{
            numbers=coins[i]%2;
            if(numbers==0){
                numbers=coins[i]/2;
            }else{
                numbers=parseInt(coins[i]/2)+1;
            }
        }
        result +=numbers;
    }
    return result;
};
 

通过率:

 

思路:

这道题初看有些犯难,我想了很久要如何解题。后来决定先用数学方法将题目思路整理出来,再来写代码。

题目要求找出拿完所有力扣币的最少次数,在这条前提下,能拿两个力扣币就绝对不能拿一个,这样可以节约步骤。那么问题是,我们该如何确定取两个力扣币的次数?于是我想到了通过取余数来判断的方法。首先建立循环给数组内的数据元素编号,用这个数除以2,假如有余数,则说明这个数据除了拿几次两个力扣币以外,还需要单独拿一次一个力扣币的步骤。在这里利用if-else语句进行判断,余数为0,则直接用数据元素与2相除得到取完这堆硬币的拿取次数;余数不为0,拿取次数就是数据元素与2相除得到的商再加上1(拿一个力扣币的步骤)之和。最后在判断语句外将拿取次数涌单独的变量总和起来,等到循环结束,直接输出这个变量即可。这个变量每经历一次循环都会发生改变,拿取次数会逐渐相加。

这里指的注意的是,当数组元素等于1时的情况,1除以2取余数的话是等于1的,假如这种情况没有单独提出来,很容易在代码里造成误区,导致输出结果错误。

通过率的内存消耗还算合格,执行用时稍显拉跨,我在力扣的官方题解里面看了一圈,实验之下并没有找到很好的方法,解出来的思路代码大同小异,我看到有方法说用reduce+ceil方法向上取整的,但是我输入他的代码时输出结果却报错。

后来翻到下面这中方法,写的比我的代码简洁很多,省略了很多步骤,但是通过率差强人意。

代码:

var minCount = function(coins) {
   let ans = 0;
  // forEach对这个数coins进行遍历
  // Math.ceil()  方法用来向上取整
  // 比如Math.ceil(3.4) 取 4  Math.ceil(-3.4) 取 -3
  coins.forEach(c => (ans += Math.ceil(c / 2)));
  return ans;
};
通过率:
 
以及很奇怪的是,当我再次测试我自己写的代码时,通过率却急转而下,变成了这样:
下次会想办法优化代码,我的代码还是有些繁琐,也许会有别的方法可以使代码简洁一些,更容易理解。

posted on 2020-08-15 20:40  沈卢  阅读(222)  评论(0编辑  收藏  举报

导航