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次取反后最大化的数组和的主要内容,如果未能解决你的问题,请参考以下文章

贪心2:K 次取反后最大化的数组和

LeetCode1005 K次取反后最大化的数组和(贪心+Java简单排序)

leetcode每日一题:1005. K 次取反后最大化的数组和

1005. K 次取反后最大化的数组和

leetcode K 次取反后最大化的数组和

《LeetCode之每日一题》:226.K 次取反后最大化的数组和