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. 计算数组和:最后,计算并返回数组的总和。
相关推荐
吃好睡好便好13 小时前
用while循环语句求和
开发语言·学习·算法·matlab·信息可视化
王璐WL13 小时前
【C语言入门级教学】函数的概念2
c语言·数据结构·算法
不知名的忻14 小时前
B 树与 B+ 树:面试完全指南
b树·算法·面试·b+树
运筹vivo@15 小时前
2657. 找到两个数组的前缀公共数组 | 难度:中等
算法·leetcode·职场和发展·哈希表
索木木15 小时前
NCCL SHARP 和 TREE算法
java·服务器·算法
Lumbrologist15 小时前
【C++】零基础入门 · 第 1 节:第一个程序 Hello World 与编译运行
开发语言·c++
_李小白16 小时前
【C++学习笔记】新特性之inline变量
c++·笔记·学习
心中有国也有家16 小时前
hccl 架构拆解:昇腾集合通信库到底在做什么?
人工智能·经验分享·笔记·分布式·算法·架构
桀人16 小时前
C++——模板初阶(收录在专栏C++入门到精通)
开发语言·c++
小O的算法实验室16 小时前
2026年MCS,Q-learning增强MOPSO与改进DWA融合算法+复杂三维地形下特定移动机器人动态路径规划
算法