最大のサブ配列:配列アルゴリズムの問題 - レコードを学びます

抜粋现代 JavaScript 教程

カジュアルワーキング

入力は、例えば、数値の配列ですarr = [1, -2, 3, 4, -9, 6]

ミッション:連続した見つけるためarrサブアレイ、それをすべての内部および最大値を。

関数を記述しgetMaxSubSum(arr)、検索し、最大値を返すためにそれを使用して。

例えば:

getMaxSubSum([-1, 2, 3, -9]) = 5 (高亮项的加和)
getMaxSubSum([2, -1, 2, 3, -9]) = 6
getMaxSubSum([-1, 2, 3, -9, 11]) = 11
getMaxSubSum([-2, -1, 1, 2]) = 3
getMaxSubSum([100, -9, 2, -3, 5]) = 100
getMaxSubSum([1, 2, 3]) = 6 (所有项的和)
复制代码

ソリューション

遅いソリューション

我々は、すべての可能なサブセットを計算することができます。

最も簡単な方法は、各要素は、その始まりとすべてのサブアレイから計算され得ることです。

[-1, 2, 3, -9, 11]例:

// 从 -1 开始:
-1
-1 + 2
-1 + 2 + 3
-1 + 2 + 3 + (-9)
-1 + 2 + 3 + (-9) + 11

// 从 2 开始:
2
2 + 3
2 + 3 + (-9)
2 + 3 + (-9) + 11

// 从 3 开始:
3
3 + (-9)
3 + (-9) + 11

// 从 -9 开始:
-9
-9 + 11

// 从 -11 开始:
-11
复制代码

ネストされたループ書き出すようなコードは、実際にされている:すべての要素のアレイを介して外部ループを、現在の要素の後内部サイクルは、全てのサブアレイの組から計算されます。

function getMaxSubSum(arr) {
  let maxSum = 0; // 如果没有取到任何元素,就返回 0

  for (let i = 0; i < arr.length; i++) {
    let sumFixedStart = 0;
    for (let j = i; j < arr.length; j++) {
      sumFixedStart += arr[j];
      maxSum = Math.max(maxSum, sumFixedStart);
    }
  }

  return maxSum;
}

alert( getMaxSubSum([-1, 2, 3, -9]) ); // 5
alert( getMaxSubSum([-1, 2, 3, -9, 11]) ); // 11
alert( getMaxSubSum([-2, -1, 1, 2]) ); // 3
alert( getMaxSubSum([1, 2, 3]) ); // 6
alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100
复制代码

このスキームの時の複雑さはO(N2)です。それは我々が、アレイの2倍のサイズを増やす場合は、実行している時間が4倍に延長される、です。

大きな配列(1000,10000以上の項目)について、このアルゴリズムは、深刻な時間の浪費を引き起こす可能性があります。

高速ソリューション

私たちは、アレイ、現在のローカル要素と変数として格納を横断してみましょうsあなたがいる場合s、いくつかの点でマイナスとなり、それが再割り当てされますs=0すべてのs最大値が答えです。

テキストは説明をよく理解していない場合は、次のコードは、直接、本当に短い、それを参照してください。

function getMaxSubSum(arr) {
  let maxSum = 0;
  let partialSum = 0;

  for (let item of arr) { // arr 中的每个 item
    partialSum += item; // 将其添加到 partialSum
    maxSum = Math.max(maxSum, partialSum); // 记住最大值
    if (partialSum < 0) partialSum = 0; // 如果是负数就置为 0
  }

  return maxSum;
}

alert( getMaxSubSum([-1, 2, 3, -9]) ); // 5
alert( getMaxSubSum([-1, 2, 3, -9, 11]) ); // 11
alert( getMaxSubSum([-2, -1, 1, 2]) ); // 3
alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100
alert( getMaxSubSum([1, 2, 3]) ); // 6
alert( getMaxSubSum([-1, -2, -3]) ); // 0
复制代码

アルゴリズムは、時間計算量はO(N)であり、アレイを横断する必要があります。

最小限の配列

同様に

function getMaxSubSum(arr) {
  let maxSum = 0;
  let partialSum = 0;

  for (let item of arr) { // arr 中的每个 item
    partialSum += item; // 将其添加到 partialSum
    maxSum = Math.min(maxSum, partialSum); // 记住最小值
    if (partialSum > 0) partialSum = 0; // 如果是正数就置为 0
  }

  return maxSum;
}

alert( getMaxSubSum([-1, 2, 3, -9]) ); // -9
复制代码

ます。https://juejin.im/post/5d07b5d36fb9a07ef16183d9で再現

おすすめ

転載: blog.csdn.net/weixin_34384915/article/details/93177684