1005. K 次取反后最大化的数组和 : 简单分情况讨论贪心模拟题

简介: 1005. K 次取反后最大化的数组和 : 简单分情况讨论贪心模拟题

网络异常,图片无法展示
|

题目描述



这是 LeetCode 上的 1005. K 次取反后最大化的数组和 ,难度为 简单


Tag : 「优先队列(堆)」、「模拟」、「贪心」


给你一个整数数组 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 <= 10^41<=nums.length<=104
  • -100 <= nums[i] <= 100100<=nums[i]<=100
  • 1 <= k <= 10^41<=k<=104


贪心 + 分情况讨论 + 模拟



假设取反前的总和为 sumsum,取反一个任意值 xx 后,对 sumsum 的影响为 - 2 * x2x


即取反一个负数会使得结果变大,取反正数会使结果变小,取反 00 值对结果没有影响。


因此,为了让取反后的结果尽可能的大,我们应当取反 -2*x2x 尽可能大的数值。即按照「负数从小到大的顺序进行取反」。


对取反次数 kk 和 负数个数 cntcnt 进行分情况讨论:


  • k <= cntk<=cnt:按照负数从小到大的顺序进行取反即可;
  • k > cntk>cnt:按照负数从小到大的顺序进行取反后,根据「是否存在00值」和「剩余取反次数的奇偶性」进行分情况讨论:
  • 存在 00 值 或 剩余取反次数为偶数:直接返回当前取反数组的总和( 00 值可抵消任意次数的取反操作,将偶数次的取反操作应用在同一数值上,结果不变);
  • 不存在 00 值且剩余取反次数为奇数:此时从当前数值中取一个绝对值最小值(使用 idxidx 记录该值下标)进行取反,得到最终的取反数组。


最后对取反数组进行求和操作即可。


代码:


class Solution {
    public int largestSumAfterKNegations(int[] nums, int k) {
        int n = nums.length, idx = 0;
        PriorityQueue<Integer> q = new PriorityQueue<>((a,b)->nums[a]-nums[b]);
        boolean zero = false;
        for (int i = 0; i < n; i++) {
            if (nums[i] < 0) q.add(i);
            if (nums[i] == 0) zero = true;
            if (Math.abs(nums[i]) < Math.abs(nums[idx])) idx = i;
        }
        if (k <= q.size()) {
            while (k-- > 0) nums[q.peek()] = -nums[q.poll()];
        } else {
            while (!q.isEmpty() && k-- > 0) nums[q.peek()] = -nums[q.poll()];
            if (!zero && k % 2 != 0) nums[idx] = -nums[idx];
        }
        int ans = 0;
        for (int i : nums) ans += i;
        return ans;
    }
}
复制代码


  • 时间复杂度:对 numsnums 进行遍历,得到 idxidx 以及优先队列的复杂度为 O(n\log{n})O(nlogn);从优先队列中取出元素进行取反操作的复杂度为 O(k\log{n})O(klogn);对取反数组进行求和复杂度为 O(n)O(n)。整体复杂度为 O(n\log{n})O(nlogn)
  • 空间复杂度:O(n)O(n)


优化优先队列



由于 numsnums 长度范围为 1000010000,但值域范围在 [-100, 100][100,100],因此我们可以使用计数数组 cntcnt 来替代优先队列的作用。


注意由于 nums[i]nums[i] 存在负数,因此需要增 100100 的偏移量。同时对于翻转操作,仅需要修改相应计数即可。


代码:


class Solution {
    public int largestSumAfterKNegations(int[] nums, int k) {
        int[] cnts = new int[210];
        for (int i : nums) cnts[i + 100]++;
        for (int i = -100; i < 0 && k > 0; i++) {
            while (cnts[i + 100] != 0 && k-- > 0) {
                cnts[i + 100]--; cnts[-i + 100]++;
            }
        }
        if (cnts[0 + 100] == 0 && k > 0 && k % 2 != 0) {
            int val = 1;
            while (cnts[val + 100] == 0) val++;
            cnts[val + 100]--; cnts[-val + 100]++;
        }
        int ans = 0;
        for (int i = -100; i <= 100; i++) ans += i * cnts[i + 100];
        return ans;
    }
}
复制代码


  • 时间复杂度:需要对 numsnums 以及大小为 C = 210C=210 的计数数组进行常数次扫描,复杂度为 O(n + C)O(n+C)
  • 空间复杂度:O(C)O(C)


最后



这是我们「刷穿 LeetCode」系列文章的第 No.1005 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。


在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。


为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour…


在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

相关文章
|
8月前
|
传感器 监控 大数据
指挥学校大数据系统解决方案
本系统集成九大核心平台,包括中心化指挥、数据处理、学生信息、反校园欺凌大数据、智慧课堂、学生行为综合、数据交换及其他外部系统云平台。通过这些平台,系统实现对学生行为、课堂表现、校园安全等多维度的实时监控与数据分析,为教育管理、执法机关、心理辅导等提供强有力的数据支持。特别地,反校园欺凌平台利用多种传感器和智能设备,确保及时发现并处理校园霸凌事件,保障学生权益。同时,系统还涵盖超市、食堂、图书馆、消防安全等辅助云平台,全面提升校园智能化管理水平。
|
7月前
|
云安全 运维 监控
课时11:阿里云安全产品之安骑士
阿里云安骑士是一款领先的主机防护产品,致力于构建全面高效的安全防护体系。它通过轻量级Agent、实时监控、集中管理和情报共享等优势,帮助企业提前发现并修复高危漏洞,防范病毒入侵和数据泄露,确保服务器安全稳定运行。尤其在漏洞管理方面,安骑士提供一键修复功能,极大提高了响应速度,有效应对各类网络威胁。目前已为37%的中国互联网企业提供安全保障。
213 0
|
API Python
永续合约/秒合约系统设计开发dapp技术/代码搭建示例
永续合约是一种类似于期货合约的金融衍生品,与传统合约不同的是,它没有到期日期。HKD交易所的永续合约是基于标 记价格和保证金机制的交易方式,允许用户通过杠杆操作来增加收益和风险。在永续合约交易中,用户可以选择开多或开空 仓位,实现对市场走势的利润预测。
|
机器学习/深度学习 自然语言处理 算法
EasyCV开源|开箱即用的视觉自监督+Transformer算法库
EasyCV背后的算法框架如何设计?开发者可以怎么使用?未来有哪些规划?今天一起来深入了解。
EasyCV开源|开箱即用的视觉自监督+Transformer算法库
|
存储 编解码 安全
Studio One2023产品注册机最新版本下载
Studio One 6 中文特别版,现在Studio One 6终于有了视频支持,可以方便做视频配乐了。视频可以作为一个独立的音轨使用,跟乐器和音频音轨一样。你可以像音频素材一样在时间条来回拖拽视频来进行音画同步对齐。如果视频也包括了音频,那么你也可以导出音频作为一个子音轨来操作。视频音轨和子音轨也都有自己独立的混音通道可以进行各种处理,比如加载插件,设置路由等等。导出的格式支持Quicktime、MPEG-4、M4V。
1966 0
|
存储 关系型数据库 数据库
无敌!关系型数据库范式分析,第一范式、第二范式、第三范式、BC范式、第四范式、第五范式
无敌!关系型数据库范式分析,第一范式、第二范式、第三范式、BC范式、第四范式、第五范式
775 0
无敌!关系型数据库范式分析,第一范式、第二范式、第三范式、BC范式、第四范式、第五范式
|
API 区块链 数据安全/隐私保护
部署智能合约到公链
以太坊公链除了主网,还有多个测试网络。主网(Mainnet)是正式的以太坊网络,里面的以太币是真正有价值的,测试网络中的以太币没有价值,只用于测试。我们最终目标是连接到主网,但先连接到测试网络Kovan,虽然本地区块链网络(Ganache)也能测试,但与公链还是有区别的。...
557 0
部署智能合约到公链
|
API iOS开发
苹果.tbd格式的文件介绍、生成和使用
早在2015年苹果推出了Xcode7的时候,.tbd文件也随之产生,它的出现取代了我们熟悉的 .dylib。 那么.tbd文件到底是什么呢?有什么用?怎么用?接下来我们一点一点来揭开它的面纱。
苹果.tbd格式的文件介绍、生成和使用
|
数据采集 JSON Prometheus
iLogtail使用入门-iLogtail 采集Prometheus 数据
前言阿里已经正式开源了可观测数据采集器iLogtail。作为阿里内部可观测数据采集的基础设施,iLogtail承载了阿里巴巴集团、蚂蚁的日志、监控、Trace、事件等多种可观测数据的采集工作。本文将介绍iLogtail 如何采集Prometheus exporter 数据。采集配置iLogtail 的采集配置全面兼容Prometheus 配置文件(以下介绍为1.0.30版本+)。参数描述默认值Ya
1201 0
iLogtail使用入门-iLogtail 采集Prometheus 数据
|
机器学习/深度学习 人工智能 自然语言处理
ViTGAN:用视觉Transformer训练生成性对抗网络 Training GANs with Vision Transformers
ViTGAN是加州大学圣迭戈分校与 Google Research提出的一种用视觉Transformer来训练GAN的模型。该论文已被NIPS(Conference and Workshop on Neural Information Processing Systems,计算机人工智能领域A类会议)录用,文章发表于2021年10月。 论文地址:https://arxiv.org/abs/2107.04589 代码地址:https://github.com/teodorToshkov/ViTGAN-pytorch 本博客是精读这篇论文的报告,包含一些个人理解、知识拓展和总结。