通过对数组值进行加减运算而不会重叠来查找最大值

时间:2018-06-19 14:57:02

标签: algorithm sorting

输入

给出一个array,一个maximum值和一个current值。

目标

对于i中的每个array[i]array[i]必须从current加上或减去。我无法确切知道何时应该加或减以获得以下output

输出

在不高于maximum或小于0的情况下电流可以获得的最大值。如果不可能,则返回-1。

问题

我想出了以下代码段,但这是不正确的。如果我计算每个可能的答案,然后找到最大的答案,则复杂度将高于O(n)。我怎么知道什么时候减或加?

function calcMax(array, max, current) {
  let output = current;
  for (let i = 0; i < array.length; i++) {
    if (output + array[i] <= max) {
      output += array[i];
    } else {
      output -= array[i];
    }
    return output < 0 ? -1 : output;
  }
}

console.log(calcMax([5, 3, 7], 16, 5))

示例

输入:([15,2,9,10],20,8)。 正确的输出: -1

输入:([5,3,7],10,5)。 正确的输出: 10 (5-5 + 3 + 7)

输入:([5,3,7],16,5)。 正确的输出: 14 (5 + 5-3 + 7)

2 个答案:

答案 0 :(得分:0)

在我看来,问题似乎是遍历两条路径-加,减。 如果考虑加,减作为2条不同的路径,它将形成一个二叉树。例如,数组[5, 3, 7]max = 16curr = 5形成了一个二叉树:

                                    5

                              0           10

                                3       7        13

                                 10   0  14   6  

其中左子项是减法,右子项是加法。当前值为节点值,要添加的元素为A[i]

观察到二叉树不完整,因为它受到[0,max]的约束。 您会看到它没有小于0且大于最大结点的节点。

您可以实现基于队列的方法来遍历树,并在处理完所有数组元素后在最后一级找到最大值。

伪代码为:

Queue q = new Queue
q.add( current )
int i = 0 //index into array
ans = -1
while ( !q.isEmpty() AND i < A.length )
   int qsize = q.size()
   for ( int j = 0; j < qsize; j++ )
      int currVal = q.poll()
      int addValue = currVal + A[i]
      int subValue = currVal - A[i]
      if ( subValue >= 0 && subValue <= max )
         q.add( subValue );
      if ( addValue >= 0 && addValue <= max )
         q.add( addValue );

   i++

 //now we processed all array elements, now check max value obtained in the last level if any.
 while ( !q.isEmpty ) 
     ans = Math.max( ans, q.poll() )  

 return ans == current ? -1 : ans;

答案 1 :(得分:0)

我想出了一个递归解决方案。 我认为是O(n)。

const max = 50;
const current = 20
const array = [20, 30, 4, 14, 16];
let answer = -1;


function calcMax(i, value) {
    
    // Checking the bounds
    if (i === array.length)         {return value}
    if (value > max || value < 0)   {return -1}
    
    
    // With each index compare it with final answer
    let r = 0;
    if (value + array[i] <= max) {
        r = calcMax(i + 1, value + array[i]);
        if (r > answer) {
            answer = r;
        }
    }
    if (value - array[i] >= 0) {
        r = calcMax(i + 1, value - array[i]);
        if (r > answer) {
            answer = r;
        }
    }
    return r;
}


calcMax(0, current);
console.log(answer);