题目描述
解题思路
贪心思路:
第一次贪心:(如果负数大于k)
局部最优:就是每次变换变换绝对值最大的数,整体最优:整个数组和达到最大。
第二次贪心:(如果负数小于k,负数变完之后,还剩正数)
局部最优:变换最小的正数,全局最优:整个 数组和 达到最大。
那么本题的解题步骤为:
- 第一步:将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
 - 第二步:从前向后遍历,遇到负数将其变为正数,同时K—
 - 第三步:如果K还大于0,那么反复转变数值最小的元素,将K用完
 - 
写法一
public int largestSumAfterKNegations(int[] A, int K) {if (A.length == 1) return K % 2 == 1 ? -A[0] : A[0];Arrays.sort(A);int index = 0;for (int i = 0; i < K; i++) {// 如果为负数,那就变为相反数if (i < A.length - 1 && A[index] < 0) {A[index] = -A[index];// 如果变化之后大于等于后边数的绝对值,那么index++// [1,3,2,6,7,9]// 3// 注意需要判断,否则全为正数就会不满足贪心if (A[index] >= Math.abs(A[index + 1])) index++;// 下一步不执行了continue;}// 最终负数消耗完了,但是还有正数,所以一直利用最小的一个正数,把k消耗完A[index] = -A[index];}// 统计总和int sum = 0;for (int i = 0; i < A.length; i++) {sum += A[i];}return sum;}
写法二
使用stream直接对绝对值排序
public int largestSumAfterKNegations(int[] nums, int k) {int result = 0;// 将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小nums = IntStream.of(nums).boxed().sorted((o1, o2) -> Math.abs(o2) - Math.abs(o1)).mapToInt(Integer::intValue).toArray();for (int i = 0; i < nums.length; i++) {// 从前向后遍历,遇到负数将其变为正数,同时K--if (nums[i] < 0 && k > 0) {nums[i] = Math.abs(nums[i]);k--;}}if (k % 2 == 1) nums[nums.length - 1] = 0 - nums[nums.length - 1]; // 如果K还大于0,那么反复转变数值最小的元素,将K用完// 求和for (int i : nums) {result += i;}return result;}
 
