Problem Description:
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.
第一道题,这里给的是easy,自己这个白痴考虑了很多种情况,又是排序又是数正负数个数的,还分了3种情况,写了都超50行了,看了看别人写的,真的是大神,很厉害了
public int largestSumAfterKNegations(int[] A, int K) {
int[] cnt = new int[201];
int res = 0;
for (int i : A) ++cnt[i + 100];
for (int i = -100; i <= 100 && K > 0; ++i) {
if (cnt[i + 100] > 0) {
int k = i < 0 ? Math.min(K, cnt[i + 100]) : K % 2;
cnt[-i + 100] += k;
cnt[i + 100] -= k;
K = i < 0 ? K - k : 0;
}
}
for (int i = -100; i <= 100; ++i) res += i * cnt[i + 100];
return res;
}
因为-100 <= A[i] <= 100,所以这个作者的思路是通过cnt[201]数组,记录每个A[i] 出现的次数(没有出现cnt[i] = 0,出现m次,cnt[i] = m),负数是前100个,正数是后100个,这种方法自动就省略了排序,方便快捷!
还看到了另外一个博主转发的别人的代码,
public int largestSumAfterKNegations(int[] A, int K) {
PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
for(int x: A) pq.add(x);
while( K-- > 0) pq.add(-pq.poll());
int sum = 0;
for(int i = 0; i < A.length; i++){
sum += pq.poll();
}
return sum;
}
这个的代码更简洁了,这个解法充分利用了优先队列PriorityQueue。PriorityQueue的逻辑结构是一棵完全二叉树,存储结构其实是一个数组。每次add和poll后,都会自动再次排序,使得这个堆顶是最小值。
附上链接:Java堆结构PriorityQueue完全解析