Алгоритм с линейной сложностью

Алгоритм с линейной сложностью


Ответ:

const findSumOfSubarray = (arr, k) => {
  let total = 0;
  let partSum = 0;

  const map = new Map();
  map.set(0, 1);

  for (let i = 0; i < arr.length; i++) {
    partSum += arr[i];

    // found a subarray that sum of this subarray equals k
    if (map.has(partSum - k)) {
      total += map.get(partSum - k);
    }

    // add new part sum to dictionary
    if (!map.has(partSum)) {
      map.set(partSum, 0);
    }
    map.set(partSum, map.get(partSum) + 1);
  }

  return total;
};

Объяснение:

Идея решения заключается в использовании частичных сумм массива.

Рассмотрим пример, arr = [1, 2, 3]. Будем считать частичные суммы для каждого элемента, т.е.

partSum(i) = arr[0] + arr[1] + … + arr[i]

Для нашего примера массив частичных сумм будет следующим:

[1, 1 + 2, 1 + 2 + 3] = [1, 3, 6]

Нам нужно найти подмассив с суммой элементов равным K, т.е. подмассив {i, j}, где i — начальный индекс подмассива, j — конечный, а сумма его элементов Sum(i,j) = K.


Что такое Sum(i, j)?

Sum(N) = arr[0] + arr[1] + arr[2] + … + arr[i] + arr[i + 1] + … + arr[j] + arr[j + 1] + … + arr[N]

Sum(i) = arr[0] + arr[1] + arr[2] + … + arr[i]

Sum(j) = arr[0] + arr[1] + arr[2] + … + arr[i] + arr[i + 1] + … + arr[j]

Sum(i, j) — это разница между Sum(j) и Sum(i), т.е. Sum(i, j) = Sum(j) — Sum(i)


В конечном итоге, нам нужно посчитать кол-во Sum(i, j), ктр равны K. Или кол-во пар, где Sum(j) — Sum(i) = K. Sum(i) = Sum(j) — K.

Код для проверки:

const findSumOfSubarray = (arr, k) => {
  let total = 0;
  let partSum = 0;

  const map = new Map();
  map.set(0, 1);

  for (let i = 0; i < arr.length; i++) {
    partSum += arr[i];

    // found a subarray that sum of this subarray equals k
    if (map.has(partSum - k)) {
      total += map.get(partSum - k);
    }

    // add new part sum to dictionary
    if (!map.has(partSum)) {
      map.set(partSum, 0);
    }
    map.set(partSum, map.get(partSum) + 1);
  }

  return total;
};

console.log(findSumOfSubarray([1, 2, 3], 3)); // 2
console.log(findSumOfSubarray([1, 2, 3], 4)); // 0
console.log(findSumOfSubarray([1, 2, 3], 5)); // 1

console.log(findSumOfSubarray([1, 1, 1], 2)); // 2


Report Page