K次取反最大化数组和解法(力扣1005)

题目解析

力扣1005 题 "K 次取反后最大化的数组和" 要求:给定一个整数数组 nums 和一个整数 k,你可以执行最多 k 次取反操作(每次操作可以选择数组中的一个元素并将其值取反)。请返回经过最多 k 次取反操作后,能得到的最大数组和

核心思路 :采用贪心算法 。为了使数组和最大化,应优先将绝对值较大的负数 翻转为正数。如果所有负数都翻转后仍有剩余操作次数,则应反复翻转绝对值最小的元素(即当前数组中的最小正数或零),以使总和的损失最小 。

算法步骤

  1. 排序 :将数组按绝对值从大到小排序。这样能确保优先处理绝对值最大的负数 。
  2. 第一次贪心(翻转负数) :遍历排序后的数组。如果当前元素是负数且 k > 0,则将其取反(nums[i] = -nums[i]),同时 k--
  3. 第二次贪心(处理剩余翻转次数) :经过步骤2后,如果 k 仍为奇数(即 k % 2 == 1),则将数组中绝对值最小的元素 (即排序后的最后一个元素)取反一次。因为偶数次翻转同一个元素相当于没有操作,奇数次翻转则相当于取反一次,所以只需考虑 k 的奇偶性 。
  4. 求和:计算并返回最终数组的和。

复杂度分析

  • 时间复杂度:O(n log n),主要由排序操作决定 。
  • 空间复杂度:O(1) 或 O(log n)(取决于排序算法的空间开销)。

C++ 代码实现

cpp 复制代码
#include <vector>
#include <algorithm>
#include <numeric>

class Solution {
public:
    int largestSumAfterKNegations(std::vector<int>& nums, int k) {
        // 1. 按绝对值从大到小排序
        std::sort(nums.begin(), nums.end(), [](int a, int b) {
            return std::abs(a) > std::abs(b);
        });

        // 2. 第一次贪心:翻转绝对值最大的负数 for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] < 0 && k > 0) {
                nums[i] = -nums[i];
                k--;
            }
        }

        // 3. 第二次贪心:如果剩余k为奇数,翻转绝对值最小的元素(即最后一个元素)
        if (k % 2 == 1) {
            nums[nums.size() - 1] = -nums[nums.size()1];
        }

        // 4. 计算并返回数组和
        return std::accumulate(nums.begin(), nums.end(), 0);
    }
};

代码关键点解析

  • 自定义排序 :使用 std::sort 并传入 lambda 表达式,实现按绝对值降序排序,这是贪心策略的基础 。
  • 两次贪心 :第一次遍历优先处理负数,是局部最优(使当前和增加最多);第二次处理剩余 k 值,也是局部最优(使总和损失最小)。两者结合达到全局最优 。
  • 剩余 k 的处理 :只需判断 k 的奇偶性,因为对同一个元素翻转两次等于没有操作 。

参考来源

相关推荐
此生决int6 分钟前
深入理解C++系列(04)——类和对象(下)
开发语言·c++
Yeauty19 分钟前
你那条 ffmpeg 命令,一键翻成 Rust builder 代码
开发语言·rust·ffmpeg
king_linlin21 分钟前
数据结构——顺序表(附图文讲解|超详细)
c语言·数据结构·算法
GAOJ_K25 分钟前
老旧产线弧形导轨换新:同规格替换避坑选型思路
人工智能·算法·机器学习·制造·导轨偏磨
鱼香鱼香rose29 分钟前
java-2
java·开发语言·python
Jerry5 小时前
LeetCode 189. 轮转数组
算法
Jerry6 小时前
LeetCode 739. 每日温度
算法
星栈独行10 小时前
翻完 Pi 源码:它和 Codex、Claude Code 有何不同
开发语言·javascript·人工智能·程序人生
2601_9545267510 小时前
【工业传感与算法实战】温漂补偿与零点抗漂破局:基于二阶多项式拟合的 C/C++ 边缘校准算法,深度拆解“压力变送器什么牌子好”的技术硬指标
c语言·c++·算法
qq_4480111611 小时前
C语言中的变量和函数的定义与声明
android·c语言·开发语言