查找添加到数组的运行总和时为 1 的最小数

Posted

技术标签:

【中文标题】查找添加到数组的运行总和时为 1 的最小数【英文标题】:Finding the minimum number which when added to running sum of array is 1 【发布时间】:2020-11-08 21:09:42 【问题描述】:

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

例如。 arr = [-2, 3, 1, -5]。

如果 x = 4,则得到以下结果:

Running     
sum       arr[i]
-----     -----
4          -2
2           3
5           1
6          -5
1

任何想法如何找到这个。我尝试从 '0' 开始并缓慢递增直到达到 1,但我猜这是错误的方法。

【问题讨论】:

停止在你的编码挑战中作弊:p 【参考方案1】:
/******************************************************************************

Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, Java, php, Ruby, Perl,
C#, VB, Swift, Pascal, Fortran, Haskell, Objective-C, Assembly, html, CSS, JS, SQLite, Prolog.
Code, Compile, Run and Debug online from anywhere in world.

*******************************************************************************/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int minX(vector<int> &arr)

    vector<int> temp;
    int sumwX = 1;
    for(auto it = arr.begin(); it != arr.end(); ++it)
    
        sumwX += *it;
        temp.push_back(sumwX);
    
    
    return (1 - (*min_element(temp.begin(), temp.end()) - 1 ));


int main()

    
    vector<int> M = -5,4,-2,3,29,-1,-6,-1,0,-5;
    vector<int> N = -2,3,1,-5;
    vector<int> V = -5,4,-2,3,1,-1,-6,-1,0,-5;
    cout << minX(M) << endl;
    cout << minX(N) << endl;
    cout << minX(V) << endl;
    return 0;

【讨论】:

【参考方案2】:
def minX(arr):
    temp,count1,counter,found= 1,2,len(arr)-1,False
    while  counter !=-1 :
        temp+=(arr[counter] * -1)
        counter -=1
        if temp < 1 :
            temp = 0
            temp += count1
            count1 += 1
            counter = len(arr)-1
    return temp

【讨论】:

【参考方案3】:

您可以在执行过程中从左到右调整 x 的数组(Python):

In [2]: arr = [-2, 3, 1, -5]

In [3]: accum = x = 0

In [4]: for item in arr:
   ...:     accum += item
   ...:     if accum < 1:
   ...:         x += 1 - accum
   ...:         accum = 1
   ...:         

In [5]: accum
Out[5]: 1

In [6]: x
Out[6]: 4

【讨论】:

【参考方案4】:

反向进行累加,意思是:

从 1 开始,并从数组的 end 中减去 值,然后返回到数组的开头。每当您得到一个小于 1 的值时,在继续减法之前将其更正为 1。

你在完成这个算法时得到的值是你正在寻找的 x 的最小值。

在可运行的 javascript sn-p 中实现:

function getMinX(arr) 
    let x = 1;
    for (let i = arr.length - 1; i >= 0; i--) 
        x = x - arr[i];
        if (x < 1) x = 1;
    
    return x;


let arr = [-2, 3, 1, -5];
console.log(getMinX(arr)); // 4

某些语言支持函数式编程风格,您可以在其中使用fold。在 JavaScript 中将被编码为:

const getMinX = arr => arr.reduceRight((x, val) => Math.max(1, x-val), 1);

console.log(getMinX([-2, 3, 1, -5])); // 4

【讨论】:

【参考方案5】:

你应该

    计算输入整数数组的滚动和(时间 O(n)) 例如:arr = [-2, 3, 1, -5] => arr_rolling = [0, -2, 1, 2, -3] 求和中的最小元素 -- min_sum (时间 O(n)) 例如:arr_rolling = [0, -2, 1, 2, -3] => min_sum = -3 X = 1 - min_sum (时间 O(1)) 例如:min_sum = -3 => X = 4

最终的时间复杂度为 O(n)。

了解算法后,您可能会注意到无需存储滚动总和,您可以“即时”计算滚动总和最小值。一旦你注意到它,内存使用量就变成了 O(1)。

【讨论】:

您好,您能解释一下为什么您的算法有效吗?在一个桌面测试中,我看到它有效,但我不明白为什么 @CatarinaNogueira,当然。元素 X 的前置如何影响数组的滚动和?所有这些都增加 X。本质上,您需要知道“当我从第一个元素移动到最后一个元素时,滚动总和可以变得多小”。当您知道它时,您就知道什么值足以添加到数组中以“提升”这个最小值到最小的令人满意的值(在我们的例子中为 1)。比如说,最小滚动总和是 -5,那么你需要将滚动总和“提升”6。

以上是关于查找添加到数组的运行总和时为 1 的最小数的主要内容,如果未能解决你的问题,请参考以下文章

查找数组中的最小更改数以进行 k 算术级数

查找两个总和为特定值的索引

如何在运行时为结构数组赋值?

最小唯一数组总和

方格取数问题 最小割

获取数组中元素的最大值最小值平均值总和