一、题目描述
Given an array A of integers, we must modify the array in the following way: we choose an i and replace A[i] with -A[i], and we repeat this process K times in total. (We may choose the same index i multiple times.)
Return the largest possible sum of the array after modifying it in this way.
Input: A = [3,-1,0,2], K = 3
Output: 6
Explanation: Choose indices (1, 2, 2) and A becomes [3,1,0,2].
Note:
- 1 <= A.length <= 10000
- 1 <= K <= 10000
- -100 <= A[i] <= 100
二、题解
方法一:K 次排序
- 如何高效的找到最小值的索引
i
,然后将其变为-A[i]
。 - 一个朴素的做法就是,每次取反之前对数组进行升序排列,排序后的第一个元素始终是最小的。
A.length
最大 10000,K
最大 10000, 大概执行 次。勉强过…
public int largestSumAfterKNegations(int[] A, int K) {
int sum = 0;
while (K-- > 0) {
Arrays.sort(A);
A[0] = -A[0];
}
for (int n : A)
sum += n;
return sum;
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,
方法二:维护最小值下标
方法一的 K 次排序存在冗余,因为每一次排序后最小值可能还是自己,这种情况会使得下一次排序变得徒劳。我们可以这样做:
- 每次将最小值取反,然后判断下一个数字是否比取反后的数字小。
- 若是,则将 mini 指向下一个数字。
- 否则,下一轮取反时,取反当前最小值
A[mini]
会使得总和最大。
public int largestSumAfterKNegations(int[] A, int K) {
Arrays.sort(A);
int mini = 0, N = A.length;
while (K-- > 0) {
A[mini] = -A[mini];
if (mini + 1 < N && A[mini+1] < A[mini])
mini = mini + 1;
}
int sum = 0;
for (int n : A)
sum += n;
return sum;
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,