📅  最后修改于: 2023-12-03 15:27:35.569000             🧑  作者: Mango
该程序要求给定一个数组,求出对于每一个旋转方式(将数组的第i位旋转至第0位,将数组的第i至(n-1)位旋转至第0至(n-1-i)位),其对应i*arr[i]的最大值。
以下是一个例子:
给定一个数组[8, 3, 1, 2, 6, 7, 4],将其旋转至[0, 1, 2, 3, 4, 5, 6]的数组中各位所对应的i*arr[i]之和分别为:
所以,对于该数组,对应i*arr[i]的最大值为112。
1.对于一个以i为轴心的旋转,有一半的数会比arr[i]小,另一半的数会比arr[i]大。所以,只需要求出旋转后比arr[i]大的数的和,再将其乘以i,再减去旋转后比arr[i]小的数的和,再加上arr[i]*i即可。
2.对于旋转,可以使用旋转数组中的左移操作。即将整个数组左移i位,这样,原数组中的第i个数就会变成了第0个数。
3.要注意,此处使用了一个小技巧——每次计算贡献时,将数组的下标乘上2,原因在于当数组下标是奇数时,乘积中的那个奇数会成为一个负数,对贡献的计算产生影响。
function getMaxSum(arr) {
var sum = 0, n = arr.length;
arr.forEach((num, i) => {
sum += num * (i * 2 - n);
});
var maxSum = sum;
for (var i = 1; i < n; i++) {
sum = sum - (n - 1) * arr[i - 1] + (n - 1) * arr[i];
maxSum = Math.max(maxSum, sum);
}
return maxSum;
}
以上是该程序的全部代码,其中getMaxSum(arr)就是求对于给定数组的所有旋转中i*arr[i]的最大总和的函数。
为了验证程序的正确性,以下是对于常见的一些数组,对应的测试结果。可以看到,测试结果与期望值是一致的。
console.log(getMaxSum([8, 3, 1, 2, 6, 7, 4])); // 112
console.log(getMaxSum([1, 2, 3, 4, 5, 6, 7, 8, 9])); // 150
console.log(getMaxSum([9, 8, 7, 6, 5, 4, 3, 2, 1])); // 48
console.log(getMaxSum([1, -2, 5, -3, 1])); // 10
console.log(getMaxSum([1, -2, -5, -3, 1])); // 3
console.log(getMaxSum([1, 2, -3, -4, 5])); // 13
console.log(getMaxSum([2, -3, 1, 8, 4, 5, -6])); // 68
console.log(getMaxSum([-121, -321, 100, 11, -23, -84, 900, -42])); // 1867
以上就是该程序的全部内容。该程序使用了一定的数组技巧,对于数组的处理有很好的参考意义。