检查总和的算法问题

Posted

技术标签:

【中文标题】检查总和的算法问题【英文标题】:algo questions for checking sum 【发布时间】:2021-03-13 17:30:14 【问题描述】:

问题是:

从给定的整数数组和任意初始值 x 开始。从左到右计算 x 加上每个数组元素的运行总和。运行总和决不能低于 1。确定 x 的最小值。

示例:

如果数组是:arr = [-2,3,1,5] 返回值为 x = 4。

到目前为止,我的代码没有通过任何测试用例,我做错了什么? :

function minX(arr) 
    var initialSum = 0
    var runningSum= 0
    for (var i=0; i < arr.length; i++)
        if ((arr[i] + sum) <= 1)
            var diff = arr[i] + sum
            var some = 1 - diff
            initialSum = some + sum

        
        runningSum += arr[i]
    
  return initialSum

【问题讨论】:

我不懂规则。如果我尝试按照他们写在我脑海中的方式来关注它们,我认为解决方案不会是“4”。你能把它们写得更明确吗?你是什​​么意思“确定1的最小值”?这句话对我来说真的没有意义...... @AlexanderNied 这些是给定的规则,但它是这样的。我们需要从 x 的值 4 开始,因为让我们以数组中的第一个元素 (-2) 为例。 4 + (-2) = 2 大于 1。任何小于 4 的值都会将总和降至 1 或更小。这是我们需要在整个数组求和过程中维持的条件 所以你的意思不是“确定 1 的最小值”,你的意思是“确定 x 的任意初始值,这样运行总和就不会出现低于 1",对吧?因为 1 是 1——它不能有 1 以外的值。 @AlexanderNied 正确 只是一个简单的问题,为什么在示例中 x 应该是 4?作业说“运行总和永远不能低于 1”,所以它是 1 是允许的。从我所看到的 x 应该是 3 对于给定的例子。 【参考方案1】:

我将从0 开始计算总和,然后跟踪最小值。然后取你的偏移量并减去最小值。这应该为您留下一个永远不会低于给定整数数组的给定偏移量的值。

既然你的问题是:

总和不得低于 1

我选择了偏移量1,但这与预期的示例结果不匹配。然后你在 cmets 中说:

任何小于 4 的值都会将总和降至 1 或以下

这是两种截然不同的说法。如果您不想使用2,您可以在下面的sn-p 中轻松地将1 更改为2

function minX(integers) 
  let sum = 0;
  let min = 0;
  for (const integer of integers) 
    sum += integer;
    if (sum < min) min = sum;
  
  return 1 - min;


console.log(minX([-2,3,1,5]));
console.log(minX([3,-2,-4,7]));

【讨论】:

【参考方案2】:

如果我理解正确:min(x) = 0sum(n) &gt; 1

function minX(arr) 
  let minV = 0
  let sum = minV
  arr.forEach(v => 
    sum += v
    const diff = sum <= 1 ? 2 - sum : 0
    if (diff) 
      sum += diff
      minV += diff
    
  )
  return sum <= 1 ? 2 - sum : minV


console.log(minX([-2,1,3,5]))

【讨论】:

【参考方案3】:

鉴于问题陈述:

从给定的(任意)整数数组开始,然后 任意初始值x。 从左到右计算x 加上每个数组元素的运行总和。 运行总和不得低于 1。 确定 x 的最小值。

而测试用例[-2, 3, 1, 5]x的正确答案是3

对于给定的测试用例,x 作为4 的“预期值”不正确。

这是一个蛮力解决方案,它以@​​987654328@ 开头并反复尝试计算运行总和,每次违反运行总和永远不会低于 1 的约束时递增 x

function computeMinimumInitialValue(arrayOfIntegers) 
  let x = 0;
  let failure = true;

  while (failure) 
    let runningSum = x;

    for (const value of arrayOfIntegers) 

      runningSum += value;

      failure = runningSum < 1 ? true : false;
      if (failure) 
        ++x;
        break;
      

    

  ;

  return x;


const x = computeMinimumInitialValue([-2, 3, 1, 5])
console.log(x);

【讨论】:

【参考方案4】:

您在纸上的解决方案如下所示:

2 点

让我们从第一个元素 -2 开始,将 x 添加到它,你会得到 x - 2,这应该大于 1,即 x - 2 > 1。

满足这个不等式的 x 的最小值是多少?它是 x = 4,因为 4 - 2 = 2 > 1

在 3 点

下一个元素是 3,运行和是 -2 + 3 = 1。现在不等式变为 x + 1 > 1 满足这个不等式的 x 的最小值是 1。但是如果你将 x 减少到 1,它不会满足第一个不等式。所以 x 仍然是 4。

1 点

下一个元素是 1,运行总和是 -2 + 3 + 1 = 2。 不等式是 x + 2 > 1,这个不等式的 x 的最小值是 0,但你不能将它减少到 0,因为它不会满足前两个不等式。

.... ....

你明白了。计算 x 的最小值是多少,以满足每个元素的不等式,然后得到它的最大值,因为取最大值就可以满足每个元素的条件。

现在的代码是:

function minX(arr) 
    var runningSum= 0
    var res = 0, x = 0
    for (var i=0; i < arr.length; i++) 
      runningSum += arr[i]
      res = Math.max( res, runningSum < 2 ? 2 - runningSum : 0 )
    
    return res

console.log(minX([-2,3,1,-5]))
console.log(minX([1,2,-5,5]))

【讨论】:

算法不正确:你的minX([1,2,-5,5]) = 0。第一次迭代后它必须是 1,第三次之后是 4 @Darius 再仔细想想。您认为代码在最小化,但实际上却在最大化。

以上是关于检查总和的算法问题的主要内容,如果未能解决你的问题,请参考以下文章

优化算法的技巧

矩阵算法任务

动态规划算法:硬币的最大总和(小于或等于k)

在总和匹配的两组整数中查找子集的算法

JavaScript 算法题:从一个数组中找出总和最大的连续子数组

用于查找循环排序数组中正数总和的分治算法[关闭]