1005. K 次取反后最大化的数组和(力扣LeetCode)

文章目录

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

题目描述

给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:

选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。

重复这个过程恰好 k 次。可以多次选择同一个下标 i 。

以这种方式修改数组后,返回数组 可能的最大和 。

示例 1:

输入:nums = [4,2,3], k = 1

输出:5

解释:选择下标 1 ,nums 变为 [4,-2,3] 。

示例 2:

输入:nums = [3,-1,0,2], k = 3

输出:6

解释:选择下标 (1, 2, 2) ,nums 变为 [3,1,0,2] 。

示例 3:

输入:nums = [2,-3,-1,5,-4], k = 2

输出:13

解释:选择下标 (1, 4) ,nums 变为 [2,3,-1,5,4] 。

提示:

  • 1 <= nums.length <= 104
  • -100 <= nums[i] <= 100
  • 1 <= k <= 104

暴力

这段代码实现了一个特定算法,旨在通过最多K次将数组中的元素取反操作,得到修改后数组可能的最大和。下面是对这段代码的详细注释:

cpp 复制代码
class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        // 首先,对数组进行排序,目的是将负数置于数组前部,方便后续处理。
        sort(nums.begin(),nums.end());

        int sum = 0; // 初始化数组和为0。
        
        // 遍历数组,优先对负数进行取反操作。
        for(int i = 0; i < nums.size(); i++)
        {
            // 如果当前数字为负数且还有取反的机会(k>0),则将其取反。
            if(nums[i] < 0 && k > 0)
            {
                nums[i] = -nums[i]; // 取反操作
                k--; // 消耗一次取反的机会
            }
        }

        // 再次对数组进行排序,目的是处理完所有负数取反后,重新排列。
        sort(nums.begin(), nums.end());

        // 再次遍历数组,这次主要处理剩余的取反机会。
        for(int i = 0; i < nums.size(); i++)
        {
            // 如果当前元素非负,且还有取反机会
            if(nums[i] >= 0 && k > 0)
            {
                // 如果k为偶数,则无需再进行取反操作,因为偶数次取反相互抵消。
                if(k % 2 == 0)
                    k -= 2; // 直接减去2,表示偶数次取反操作不影响结果。
                else
                {
                    // 如果k为奇数,则需要对当前最小的非负数进行一次取反,保证结果是最大的。
                    nums[i] = -nums[i];
                    k--; // 消耗一次取反机会
                }
            }
            // 计算当前序列的和
            sum += nums[i];
        }
        // 返回最终的数组和
        return sum;
    }
};

算法逻辑概述:

  1. 排序:先对数组进行一次排序,将负数放在数组的前面。
  2. 负数取反 :遍历数组,对负数进行取反操作,直到没有取反机会(k用尽)或没有负数为止。
  3. 再次排序:对处理后的数组再次进行排序,这样最小的非负数(可能之前是负数)会排在数组的最前面。
  4. 处理剩余的取反机会 :再次遍历数组,如果还有取反的机会,优先对最小的非负数进行取反(因为如果k为奇数,只能对一个数取反,为了最大化数组和,应该对最小的数取反)。
  5. 计算数组和:最后,计算并返回数组的总和。
相关推荐
凉茶钱1 分钟前
【c语言】动态内存管理:malloc,calloc,realloc,柔性数组
c语言·c++·vscode·柔性数组
脏脏a1 分钟前
【C++模版】泛型编程:代码复用的终极利器
开发语言·c++·c++模版
island13141 分钟前
【C++仿Muduo库#3】Server 服务器模块实现上
服务器·开发语言·c++
散峰而望1 分钟前
【算法竞赛】C/C++ 的输入输出你真的玩会了吗?
c语言·开发语言·数据结构·c++·算法·github
小龙报2 分钟前
【C语言】内存里的 “数字变形记”:整数三码、大小端与浮点数存储真相
c语言·开发语言·c++·创业创新·学习方法·visual studio
躺不平的理查德2 分钟前
时间复杂度与空间复杂度备忘录
数据结构·算法
yaki_ya2 分钟前
yaki-C语言:从概念基础到内存解析---数组(array)完全指南
java·c语言·算法
刃神太酷啦3 分钟前
扒透 STL 底层!map/set 如何封装红黑树?迭代器逻辑 + 键值限制全手撕----《Hello C++ Wrold!》(23)--(C/C++)
java·c语言·javascript·数据结构·c++·算法·leetcode
2301_789015626 分钟前
C++:继承
c语言·开发语言·c++
星河耀银海8 分钟前
C++ 运算符重载:自定义类型的运算扩展
android·java·c++