给出一个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)
答案 0 :(得分:0)
在我看来,问题似乎是遍历两条路径-加,减。
如果考虑加,减作为2条不同的路径,它将形成一个二叉树。例如,数组[5, 3, 7]
和max = 16
,curr = 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);