您可以从整数k获得的最高产品

时间:2016-11-27 13:14:12

标签: javascript algorithm greedy

我正在解决以下问题:

  

给定一个arrayOfInts,找到你可以从整数k得到的最高产品。

这是我迄今为止提出的解决方案,它基于从3个整数中获取最高产品的概括。

var getHighestProductOfk = function (arrayOfInts, k) {
  if (arrayOfInts.length < k) {
    throw Error('Array should be higher than k');
  }

  highestProductArray = [arrayOfInts[0]];
  lowestProductArray = [arrayOfInts[0]];

  for (let i=1; i<k; i++) {
    highestProductArray[i] = highestProductArray[i-1]*arrayOfInts[i];
    lowestProductArray[i] = lowestProductArray[i-1]*arrayOfInts[i];
  }

  for(let i=1; i<arrayOfInts; i++) {
    let currentInt = arrayOfInts[i];

    for(let j=k-1; j>=0; j--) {
      highestProductArray[j] = Math.max(
        highestProductArray[j],
        highestProductArray[j-1]*currentInt,
        lowestProductArray[j-1]*currentInt
      );

      lowestProductArray[j] = Math.min(
        lowestProductArray[j],
        lowestProductArray[j-1]*currentInt,
        highestProductArray[j-1]*currentInt
      );
    }

    // highest number
    highestProductArray[0] = Math.max(highestProductArray[0], currentInt)

    // lowest number
    lowestProductArray[0] = Math.max(lowestProductArray[0], currentInt)
  }

  return highestProductArray[k-1];
}

知道我做错了什么吗? 对于以下示例[1,10,-5,1,-100],结果为-50而不是5000。 最小数字是1,最高数字是1而不是-100和10

三个整数的最高产品的解决方案:

var getHighestProductOfThree = function (arrayOfInts) {
  if (arrayOfInts.length < 3) {
    throw Error('Array should be higher than 3');
  }

  let highestProductOfThree = arrayOfInts[0]*arrayOfInts[1]*arrayOfInts[2];

  let highestProductOfTwo = arrayOfInts[0]*arrayOfInts[1];
  let lowestProductOfTwo = arrayOfInts[0]*arrayOfInts[1];

  let highest = arrayOfInts[0];
  let lowest = arrayOfInts[0];

  for (let i=1; i<arrayOfInts.length; i++) {
    let currentInt = arrayOfInts[i];

    highestProductOfThree = Math.max(
      highestProductOfThree,
      highestProductOfTwo*currentInt,
      lowestProductOfTwo*currentInt
    );

    highestProductOfTwo = Math.max(
      highestProductOfTwo,
      currentInt*highest,
      currentInt*lowest
    );

    lowestProductOfTwo = Math.min(
      lowestProductOfTwo,
      currentInt*lowest,
      currentInt*highest
    );

    highest = Math.max(
      highest,
      currentInt
    );

    lowest = Math.min(
      lowest,
      currentInt
    );

  }

  return highestProductOfThree;
}

3 个答案:

答案 0 :(得分:1)

这是一个想法。对数字进行排序。接下来,尽可能多地从最大的正数中选择,直到k。现在从最小的负数中挑选最大的偶数组,形成比最小的正数更大的产品,我们将用它们代替。 (有一些边缘情况,例如只有一个负面和k - 1正面)。

Pick 3 from [1, 10, -5, 1, -100]

Sort => [-100,-5,1,1,10]

Pick largest positives => 10 * 1 * 1

Pick largest even number of smallest negatives we can,
whose product is greater than the one replaced

  => (-100) * (-5) > 1 * 1

Answer => 10 * (-100) * (-5)

答案 1 :(得分:0)

根据我的初步想法,我建议对值进行排序,取最高值,如果计数为奇数,则使用其余成对。

这使得积极的产品具有循环,直到使用所有需要的因素。

在带有计数检查的while循环中,如果产品是greate而不是数组的开头,则选择对。这包括负数,但也适用于正数或负数。

function getHighestProductOfK(a, k) {
    var p = 1;

    a.sort(function (a, b) { return a - b; });
    if (k > a.length || k & 2 && a[a.length - 1] < 0) {
        return;
    }
    if (k % 2) {
        p = a.pop();
        k--;
    }
    while (k) {
        p *= a[0] * a[1] > a[a.length - 2] * a[a.length - 1] ? a.shift() * a.shift() : a.pop() * a.pop();
        k -= 2;
    }
    return p;
}

console.log(getHighestProductOfK([1, 10, -5, 1, -100], 3));
console.log(getHighestProductOfK([3, 4, 5, 6, 7], 3));
console.log(getHighestProductOfK([-3, -4, -5, -6, -7], 3));
console.log(getHighestProductOfK([3, 4, -5, -6, -7], 3));

答案 2 :(得分:0)

需要进行一些测试,以确保它总能给出好的答案。

function largestProduct(k, arr) {
    if (k > arr.length) throw new RangeError('Not enough numbers');

    let pos = [],
        neg = [];
    arr.forEach(e => {
        if (e >= 0) pos.push(e);
        else neg.push(e);
    });
    pos.sort((a, b) => a < b); //  9,  8,  7, ...
    neg.sort((a, b) => a > b); // -9, -8, -7, ...

    if (pos.length === 0 && k % 2) // k requires odd number of negatives
        return neg.slice(-k); // give the smallest number TODO: same return

    let big = [];
    while (k > 1) grow();
    if (k === 1) { // we've reached the end of doubles but still need more
        if (pos.length) big.push(pos[0]);
        else { // ran out of positives, backtrack
            big = big.slice(0, -1);
            big.push(neg[0], neg[1]);
        }
    }

    return {
        factors: big,
        product: big.reduce((a, b) => a * b, 1)
    };

    function grow() { // choose the next best number
        let doublepos = pos[0] * pos[1],
            doubleneg = neg[0] * neg[1];
        if (doublepos > doubleneg || doubleneg !== doubleneg) {
            big.push(pos[0]);
            pos = pos.slice(1);
            k -= 1;
        } else {
            big.push(neg[0], neg[1]);
            neg = neg.slice(2);
            k -= 2;
        }
    }
}