Java求解K次取反后最大化的数组和
Posted 南淮北安
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java求解K次取反后最大化的数组和相关的知识,希望对你有一定的参考价值。
一、题目
给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。(我们可以多次选择同一个索引 i。)
以这种方式修改数组后,返回数组可能的最大和。
二、题解
如何让数组和最大 ?
贪心的思路,局部最优:让绝对值大的负数变为正数,当前数值达到最大,整体最优:整个数组和达到最大。
局部最优可以推出全局最优。
那么如果将负数都转变为正数了,K依然大于0,此时的问题是一个有序正整数序列,如何转变K次正负,让 数组和 达到最大。
那么又是一个贪心:局部最优:只找数值最小的正整数进行反转,当前数值可以达到最大(例如正整数数组5, 3, 1,反转1 得到-1 比 反转5得到的-5 大多了),全局最优:整个 数组和 达到最大。
所以本题的解题步骤:
- 第一步:将数组按照绝对值大小,从小到大排序
- 第二步:从后向前遍历,遍历过程中,将负的变为正的,同时k–
- 第三步:如果遍历结束后,k 依然大于0,然后根据k的值改变最小的值 nums[0]
- 第四步:求和
三、代码
class Solution
public int largestSumAfterKNegations(int[] nums, int k)
Integer[] arr = new Integer[nums.length];
int sum = 0;
// 将基本数据类型 nums 转为引用类型
for (int i = 0; i < nums.length; i++)
arr[i] = nums[i];
// 自定义按照绝对值由大到小排序
Arrays.sort(arr, (a, b) -> Math.abs(a) - Math.abs(b));
// 从后向前遍历,将负数变为正数,同时 k--
for (int i = arr.length - 1; i >= 0 && k > 0; i--)
if (arr[i] < 0)
arr[i] = -arr[i];
k--;
// 遍历结束,k 依然大于0,然后改变最小的值 arr[0]
if (k > 0)
arr[0] = k % 2 == 0 ? arr[0] : -arr[0];
for (Integer i : arr)
sum += i;
return sum;
四、总结
自定义数组排序,可以使用 Comparator,需要注意数组类型一定要为整型,所以需要先把数组 num 转为引用类型
第一位大于第二位是从小到大排序
Integer[] arr = new Integer[nums.length];
int sum = 0;
// 将基本数据类型 nums 转为引用类型
for (int i = 0; i < nums.length; i++)
arr[i] = nums[i];
Arrays.sort(arr, new Comparator<Integer>()
@Override
public int compare(Integer o1, Integer o2)
return Math.abs(o1) - Math.abs(o2);
);
也可以利用 lambada 表达式,简写自定义排序:
Arrays.sort(arr,(a,b)->Math.abs(a)-Math.abs(b));
或者
Arrays.sort(arr,(a,b)->Integer.compare(Math.abs(a),Math.abs(b)));
以上是关于Java求解K次取反后最大化的数组和的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode1005 K次取反后最大化的数组和(贪心+Java简单排序)