力扣第1005题 K 次取反后最大化的数组和 c++ 贪心 双思维

news2024/9/27 5:42:00

题目

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。
  •         这里有个问题,如果我们仅仅只考虑绝对值最小的那个负数,需要取反多少次呢?显然,如果可取反的次数 k 为奇数,那么最终结果就是把绝对值最小的那个负数取反,而如果可取反的次数 k 为偶数,则不需要取反它。
  •         另一方面,如果可取反的次数 k 为偶数,那么显然数组中所有的数都会保持不变。最后,我们只需简单地处理一下数组的和即可。

复杂度

        时间复杂度:

                O(n * logn)

        时间复杂度:排序的时间复杂度为 O(nlogn),for 循环的时间复杂度为 O(n),因此总的时间复杂度为 O(nlogn + nlogn + n) = O(nlogn)。

        空间复杂度

                O(1)

        空间复杂度:除了输入的数组外,算法只涉及到常量级别的额外空间。因此空间复杂度为 O(1)。

c++ 代码一

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end()); // 对数组进行排序,使得负数排在前面
        int min1 = 1000; // 初始化绝对值最小的元素为一个较大的数
        int min2 = 0; // 记录绝对值最小的元素的索引

        for (int i=0; i<nums.size(); i++) {
            if(abs(nums[i]) <= min1) {  // 如果当前元素的绝对值小于等于min1
                min1 = abs(nums[i]); // 更新min1为当前元素的绝对值
                min2 = i; // 记录绝对值最小的元素的索引
            }

            if(nums[i] < 0 && k > 0) { // 如果当前元素是负数且还有剩余的翻转次数
                nums[i] *= -1; // 将当前元素取反
                k--; // 翻转次数k减一
            }
        }

        if(k%2 == 1) // 如果剩余的翻转次数是奇数
            nums[min2] *= -1; // 将绝对值最小的元素取反

        int ans = 0;
        for(int n : nums)
            ans += n; // 计算数组中所有元素的和

        return ans; // 返回最终的数组和作为结果
    }
};

思路和解题方法二

  • 对数组进行排序
  • 排序函数中采用自定义比较器的方式,把按照绝对值从大到小进行排序。这样排序后,数组中绝对值最大的元素会排在数组的最末尾,而绝对值最小的元素则会排在数组的最前面。

  • 取反负数
  • 遍历数组,如果当前的元素是负数,那么就把它取反(变为正数),同时将剩余可取反次数减一。注意我们要在剩余可取反次数大于 0 且当前元素是负数的情况下才能取反。

  • 处理无法取反的情况
  • 如果我们完成了步骤 2 后,还有剩余可取反的次数,但已经不存在可以被取反的元素了,那么我们需要对数组进行调整,使得我们所取反的元素的绝对值最小。具体地说,我们需要在数组的最末尾找到一个元素,并将它取反。因为这个元素绝对值最大,所以取反后对原来的和的影响最小。由于我们对数组进行了排序,因此直接访问最末尾的元素即可。

  • 计算数组的和
  • 遍历整个数组,计算所有元素之和即可。最终的和就是我们的答案。

复杂度

        时间复杂度:

                O(n * logn)

        时间复杂度:排序的时间复杂度为 O(nlogn),for 循环的时间复杂度为 O(n),因此总的时间复杂度为 O(nlogn + nlogn + n) = O(nlogn)。

        空间复杂度

                O(1)

        空间复杂度:除了输入的数组外,算法只涉及到常量级别的额外空间。因此空间复杂度为 O(1)。

c++ 代码二

class Solution {
    // 定义排序比较器,按照绝对值从大到小排序
    static bool cmp(int a, int b) {
        return abs(a) > abs(b);
    }
public:
    int largestSumAfterKNegations(vector<int>& A, int K) {
        sort(A.begin(), A.end(), cmp);       // 第一步:对数组进行排序
        
        for (int i = 0; i < A.size(); i++) { // 第二步:取反负数
            if (A[i] < 0 && K > 0) {
                A[i] *= -1;
                K--;
            }
        }
        
        if (K % 2 == 1) A[A.size() - 1] *= -1; // 第三步:处理无法取反的情况
        
        int result = 0;
        for (int a : A) result += a;        // 第四步:计算数组和
        
        return result;
    }
}

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1130744.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Javascript】通过浏览器书签构建与执行自动刷新脚本

0x00 前言 日常工作中&#xff0c;经常遇到需要时不时点一下刷新这样的事情&#xff08;怪前端想不到写一个自动刷新&#xff09; 但是…… 没有自动刷新按钮&#xff0c;在这页面手动点刷新还是太浪费时间了。 有时候懒得等了去做别的事情&#xff0c;过一小时回来刷新一下&a…

k8s之Flannel网络插件安装提示forbidden无权限

一、问题描述 在安装k8s的网络插件时&#xff0c;提示如下信息&#xff0c;各种forbidden无权限 [rootzzyk8s01 scripts]# kubectl apply -f kube-flannel.yml Error from server (Forbidden): error when retrieving current configuration of: Resource: "policy/v1b…

Vue中使用Web Serial API连接串口,实现通信交互

Vue中使用Web Serial API连接串口&#xff0c;实现通信交互 Web Serial API&#xff0c;web端通过串口与硬件通信; 该API是JS本身 navigator 对象上就独有的&#xff0c;所以与Vue和React框架开发都没有太大的关系&#xff0c; 串口是一个双向通信接口&#xff0c;允许字节发送…

ES6 模块化编程 详解

目录 一、基本介绍 二、基本原理示意图 三、传统CommonJS实现模块化编程 1.介绍 : 2.实例 : 四、ES6新特性实现模块化编程 1.介绍 : 2.实例 : 一、基本介绍 (1) ES6新特性——模块化编程&#xff0c;用于解决传统非模块化开发中出现的"命名冲突", "文件…

LDAP和Kerberos疑难问题诊断方法

不同的工具和方法总能给问题的解决带来希望。本文使用SSSD工具诊断Kerberos和LDAP登录问题诊断。后端&#xff08;通常也称为数据提供程序&#xff09;是管理和创建缓存的 SSSD 子进程。此过程与LDAP服务器通信&#xff0c;执行不同的查找查询并将结果存储在缓存中。它还针对 L…

PY32F002A系列单片机:高性价比、低功耗,满足多样化应用需求

PY32F002A系列微控制器是一款高性能、低功耗的MCU&#xff0c;它采用32位ARM Cortex-M0内核&#xff0c;最高工作频率达到24MHz&#xff0c;提供了强大的计算能力。此外&#xff0c;PY32F002A拥有最大20Kbytes的flash存储器和3Kbytes的SRAM&#xff0c;为简单的数据处理提供了充…

一文速通Nginx网关与gateway网关区分

目录 API网关介绍 gateway基本介绍 Nginx基本介绍 Nginx与API gateway网关 API网关介绍 网关的角色是作为一个 API 架构&#xff0c;用来保护、增强和控制对于 API 服务的访问。API 网关是一个处于应用程序或服务&#xff08;提供 REST API 接口服务&#xff09;之前的系…

创建 Edge 浏览器扩展教程(上)

创建 Edge 浏览器扩展教程&#xff08;上&#xff09; 介绍开始之前后续步骤开始之前1&#xff1a;创建清单 .json 文件2 &#xff1a;添加图标3&#xff1a;打开默认弹出对话框 介绍 在如今日益数字化的时代&#xff0c;浏览器插件在提升用户体验、增加功能以及改善工作流程方…

Spring Authorization Server 1.1 扩展 OAuth2 密码模式与 Spring Cloud Gateway 整合实战

目录 前言无图无真相创建数据库授权服务器maven 依赖application.yml授权服务器配置AuthorizationServierConfigDefaultSecutiryConfig 密码模式扩展PasswordAuthenticationTokenPasswordAuthenticationConverterPasswordAuthenticationProvider JWT 自定义字段自定义认证响应认…

【AI视野·今日Robot 机器人论文速览 第五十八期】Thu, 19 Oct 2023

AI视野今日CS.Robotics 机器人学论文速览 Thu, 19 Oct 2023 Totally 25 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers InViG: Benchmarking Interactive Visual Grounding with 500K Human-Robot Interactions Authors Hanbo Zhang, Jie Xu, Yuch…

『heqingchun-Qt的艺术-优雅界面设计开发』

Qt的艺术-优雅界面设计开发 效果图 一、新建Qt窗口工程 二、准备资源文件 1.图标资源 链接: 图标资源 2.Qss资源 链接: Qss资源 三、设计开发 项目源码链接: CSDN资源

随机生成一个指定边数多边形

随机生成一个指定边数多边形 算法背景&#xff1a;我们想完成一个可以随机生成指定边数多边形的算法。在生成过程中&#xff0c;需要避免随机点连接过程中交叉的问题。 算法步骤   1、为了随机生成一个n边形&#xff0c;我们先随机生成n个点。例如下图&#xff0c;我们随机生…

AI Chatbot 对企业降低人力成本和提高竞争力的作用

随着人工智能技术的发展&#xff0c;越来越多的企业开始尝试将AI ChatBot引入到业务中。AI Chatbot是一种基于人工智能技术的智能对话机器人。它可以模拟人类对话&#xff0c;通过自然语言处理和机器学习算法来理解和回答用户的问题&#xff0c;可以帮助企业降低成本和提高效率…

ExoPlayer架构详解与源码分析(7)——SampleQueue

系列文章目录 ExoPlayer架构详解与源码分析&#xff08;1&#xff09;——前言 ExoPlayer架构详解与源码分析&#xff08;2&#xff09;——Player ExoPlayer架构详解与源码分析&#xff08;3&#xff09;——Timeline ExoPlayer架构详解与源码分析&#xff08;4&#xff09;—…

上海亚商投顾:沪指放量反弹 两市超4500股飘红

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日集体反弹&#xff0c;深成指、创业板指盘中涨超1%&#xff0c;黄白二线大幅分化&#xff0c;题材…

视频配音软件有哪些?推荐几款好用的视频配音软件

视频配音软件有哪些&#xff1f;推荐几款好用的视频配音软件 不知道大家有没有这样的体会&#xff0c;我们在观看视频作品的时候&#xff0c;如果没有声音&#xff0c;就会少了很多韵味和可供思索的空间&#xff0c;相反&#xff0c;好的配音可以为作品增色&#xff0c;一句台…

docker 搭建 flink 并上传任务

文章目录 一、docker 搭建 flink1、选择合适的 flink 版本2、重新创建 JobManager、TaskManager 容器并挂载配置文件 二、flink 简单示例1、创建项目架构2、批处理简单示例3、流处理简单示例4、上传 flink 集群①、UI 界面提交任务②、命令提交任务 5、web-ui 提交查看撤销任务…

区块链技术与应用 【全国职业院校技能大赛国赛题目解析】第五套区块链系统部署与运维

第五套区块链系统部署与运维题目 环境 : ubuntu20 fisco : 2.8.0 子任务1-2-1: 登陆Linux服务器,安装并部署下图所示的单机、四机构、三群组、八节点的星形组网拓扑区块链系统,具体工作内容如下 此题在官网有例子如图: 每个机构拥有两个节点,机构A属于中心,属于群组1,…

Linux文件系统 struct dentry 结构体解析

文章目录 前言一、目录项简介二、struct dentry2.1 简介2.2 dentry和inode关联2.3 目录项状态2.4 目录项特点 三、dentry cache3.1 简介3.2 dentry cache 初始化3.3 dentry cache 查看 四、dentry与mount、file的关联五、其他参考资料 前言 这两篇文章介绍了: VFS 之 struct f…

10月26日,起立LG新品首发第五代OLED透明显示屏

“聚力蓝海显示屏&#xff0c;合作共赢”&#xff0c;10月26号14:30分&#xff0c;起立携手LG于德金会展国际酒店&#xff0c;对起立自主研发新品第五代OLED透明显示屏首发&#xff0c;欢迎各大商业人士莅临参与&#xff0c;一起挖掘显示屏在当下内卷泛滥的时代新商机。 一、央…