一、題目描述
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;
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,