求最小切片的绝对和-codility

时间:2018-08-28 18:43:03

标签: javascript algorithm

您好,我接受了两次Codility测试并获得了0分。请帮助我使用JavaScript解决问题。

给出了一个由N个整数组成的非空数组A。一对整数(P,Q),使0≤P≤Q

一个最小abs切片的绝对总和是最小的。

例如,数组A这样:

A[0] = 2
A[1] = -4
A[2] = 6
A[3] = -3
A[4] = 9

包含以下内容:

  • (0,1),其绝对和为= | 2 +(-4)| = 2
  • (0,2),其绝对和为= | 2 +(-4)+ 6 | = 4
  • (0,3),其绝对和为= | 2 +(-4)+ 6 +(-3)| = 1
  • (1,3),其绝对和为= |(-4)+ 6 +(-3)| = 1
  • (1,4),其绝对和为= |(-4)+ 6 +(-3)+ 9 | = 8
  • (4,4),其绝对和为= | 9 | = 9

两个切片(0,3)和(1,3)均为最小abs切片,它们的绝对和为1。

编写函数:

function solution(A);

在给定一个由N个整数组成的非空数组A的情况下,返回最小abs切片的绝对和。

为以下假设写出有效的算法:

  • N是[1..1,000,000]范围内的整数;
  • 数组A的每个元素都是一个在[−10,000..10,000]范围内的整数;

这是我的解决方法:

function solution(A, i = 0, sum = 0) {
  const N = A.length;
  if (N === 0) {
    return 0;
  }
  if (N == 1) {
    return Math.abs(A[0]);
  }
  A.sort();

  // All positives 
  if (A[0] >= 0 && A[N - 1] >= 0) {
    return Math.abs(A[0]);
  }
  // All Negatives
  if (A[0] <= 0 && A[N - 1] <= 0) {
    return Math.abs(A[N - 1]);
  }
  let currAbsSum = 0;
  let minAbsSum = Number.MAX_SAFE_INTEGER;
  for (var i = 0; i < N; i++) {
    let j = N - 1;
    while (j >= i) {
      currAbsSum = Math.abs(A[i] + A[j]);
      if (currAbsSum === 0) {
        return 0;
      }
      minAbsSum = Math.min(currAbsSum, minAbsSum);
      if (Math.abs(A[i]) > Math.abs(A[j])) {
        i++;
      } else {
        j--;
      }
    }
    if (A[i] > 0) break;
  }
  return minAbsSum;
}

1 个答案:

答案 0 :(得分:2)

这是来自here的O(n log n)答案的JavaScript版本:

function solution(A) {
	let sums = new Array(A.length + 1);
	let minAbsSum = Number.MAX_SAFE_INTEGER;

	sums[0] = 0;
	
	for (var i = 0; i < A.length; i++) {
		sums[i + 1] = A[i] + sums[i];
	}

	sums.sort();

	for (var i = 1; i < sums.length; i++) {
		minAbsSum = Math.min(minAbsSum, Math.abs(sums[i] - sums[i - 1]));
	}
  
  return minAbsSum;
}

console.log(solution([2, -4, 6, -3, 9]))
console.log(solution([10, 10, 10, 10, 10, -50]))