javascript 如何设计这种解决方案,以应对来自www.example.com的不可构建的变更挑战Algoexpert.io

yx2lnoni  于 2023-05-27  发布在  Java
关注(0)|答案(7)|浏览(119)

我正在通过algoexpert.io编码挑战,我很难理解标题为不可构造的更改的问题之一的建议解决方案
下面是挑战性的问题:
给定一个正整数数组,表示您拥有的硬币的价值,编写一个函数,返回您无法创建的最小找零金额(最小金额)。给定的硬币可以具有任何正整数值,并且不一定是唯一的(即,您可以具有相同值的多个硬币)。
例如,如果你有硬币= [1,2,5],你不能创建的最小变化量是4。如果你没有硬币,你不能创造的最小变化量是1。

// O(nlogn) time, O(n) size.
function nonConstructibleChange(coins) {
  coins = coins.sort((a, b) => a - b); // O(nlogn) time operation
  let change = 0;

  for (coin of coins) {
    if (coin > change + 1) return change + 1;
    change += coin;
  }

  return change + 1;
}

我的问题
我不完全确定解决方案的作者是如何得出这样的直觉的

if the current coin is greater than `change + 1`, the smallest impossible change is equal to `change + 1`.

我可以看到它是如何跟踪的,而且算法确实通过了所有测试,但我想知道更多关于我可以用来设计这个规则的过程。
感谢您花时间阅读问题!

c9x0cxw0

c9x0cxw01#

这一个也花了我一段时间,但这是我如何理解它的:
假设你已经证明你可以赚1-8美分。
你进入下一个迭代,想知道你是否能赚9美分。所以你迭代到排序列表中的下一个新硬币。
如果newCoin < 9:

  • 你知道你可以赚9美分。
  • 例如,如果新硬币是5:用那枚新硬币从你想赚的总数中减去它。9 - 5 = 4。然后无论你之前做了4,只要再做一次。(你已经证明你可以赚1-8美分)

如果newCoin == 9:

  • 你知道你可以赚9美分。
  • 就用9分硬币吧

如果newCoin > 9:

  • 你知道一个事实,你不能使9美分
  • 这是因为你不能使用新硬币。例如,当你想赚9美分时,一枚10美分的硬币对你来说是无用的,因为它太大了(不能赚9美分)。
    *如果你不使用新的硬币,你也会被搞砸因为如果你把所有你看到的硬币加起来,你只能得到8(不能得到9)

这就是变化+1的来源。(变量变化= 8)

if the current coin is greater than `change + 1`, the smallest impossible change is equal to `change + 1`.
w41d8nur

w41d8nur2#

当整数被排序时,我们总是可以通过对排序后的整数进行累积求和来跟踪最高的可构造值。
例如,coins = [1, 2, 5] ==> 1,2,3,5,6,7
在任何一点上,如果下一个整数大于max constructible + 1,那么就没有办法构造max constructible + 1。

[1]       mc=1     ---> 2
[1, 2]    mc=3     ---> 4
[1, 2, 5] mc=7     ---> 8

如果当前整数大于mc + 1,则最小的不可能变化等于mc + 1
所以在这种情况下,对于[1, 2, 5],最小值是4。
可以这样做(我用的是go)

func NonConstructibleChange(array []int) int {
        sort.Ints(array)
        ncc :=1
        for i:=0; i< len(array) && array[i]<=ncc; i++{
            ncc +=array[i]
        }
        return ncc
    }
iovurdzv

iovurdzv3#

经过一段时间的思考,我认为这是一个概率问题。我的意思是,给定N个硬币,有多少变化是可能的?
这意味着我应该合并每一种可能性。例如,给定coins = [1, 5, 9],可以进行的最小更改量是多少?
得到possible changes = [1, 6, 10, 15, 14, 9]
那么,使用这3个硬币[1, 5, 9]可以创建的最小找零金额应该是2
顺便说一句,如果是这样的话,这是一个O(2^n) time,因为对于每一个新的硬币(每一个新的可能性),计算的数量翻了一番。
不幸的是,事实并非如此。。

j8ag8udp

j8ag8udp4#

来自AlgoExpert评论@jfebrian:
一开始我也不明白,但现在我明白了。我就是这样得到它的。
假设我们的minimum_change是7,这基本上意味着我们目前的硬币可以从1,2,3,...,7开始。
现在,我们已经有了一个事实,我们可以从1到7制作任何硬币,对吗?然后,无论我们向它添加什么硬币(n),我们都将能够使n+1,n+2,n+3,... n+7。
现在,n必须小于minimum_change + 1才能将其添加到最小变化的原因是:
如果n大于minimum_change+1,那么我们就不能用我们的硬币做minimum_change+1。
例如,我们的新硬币是9。我们可以做9+1,9+2,...,9+7,但我们不能做8。为了得到8,我们需要任何小于或等于8的硬币。
如果我们有8个,我们就可以用那个硬币。如果我们有7,我们可以加1。如果我们有6,我们可以添加2,等等。

f0ofjuux

f0ofjuux5#

我设法在没有+1的情况下解决了这个问题,通过跟踪当前最小的不可能变化,像这样:

function nonConstructibleChange(coins) {
  let currentMinImpossibleChange = 1;
    
  const sortedCoins = coins.sort((a,b) => a-b)
    
  for(let i = 0; i < sortedCoins.length ; i += 1) {
    if(currentMinImpossibleChange < sortedCoins[i]) return currentMinImpossibleChange
    currentMinImpossibleChange += sortedCoins[i];
  }
    
  return currentMinImpossibleChange;
}
ego6inou

ego6inou6#

对我来说,关键是:
有了硬币[1,2],我们知道我们可以创造1,2,3。那么,如果我们添加一个新的硬币:
a)加上4 -> [1,2,4],我们可以创建4,4+1,4+2,4+3
B)加上5 -> [1,2,5],我们可以创建5,5+1,5+2,5+3,但不能创建4
所以这就是为什么你不能创建amountOfChange + 1,如果新的硬币> amountOfChange + 1换句话说,你不能创建4,如果新的硬币是5或更大

2o7dmzc5

2o7dmzc57#

它帮助我理解了解决方案,当我试图解决它的情况下,一个分数硬币的价值是可能的。例如,如果硬币可能有0.5和2.5的价值(我个人见过这样的旧硬币)。
在这种情况下,我们需要将下一个硬币与迄今为止的最小变化+可能的最小硬币值的值进行比较。
假设我们有1.5的零钱,但下一个硬币是2.5:
2.5> 1.5 + 0.5(而不是1,现在0.5是最小的硬币),那么我们得出1.5 + 0.5 = 2是最小的不可构造变化
只需将change + 1视为change + smallestPossibleCoinValue,其中smallestCoinValue是可能的最小硬币值,仅限于此特定任务的“1”(硬币数组是整数数组)。

相关问题