【LeetCode贪心#05】K 次取反后最大化的数组和(自定义sort、二重贪心)
K次取反后最大化的数组和
给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。(我们可以多次选择同一个索引 i。)
以这种方式修改数组后,返回数组可能的最大和。
示例 1:
- 输入:A = [4,2,3], K = 1
- 输出:5
- 解释:选择索引 (1,) ,然后 A 变为 [4,-2,3]。
示例 2:
- 输入:A = [3,-1,0,2], K = 3
- 输出:6
- 解释:选择索引 (1, 2, 2) ,然后 A 变为 [3,1,0,2]。
示例 3:
- 输入:A = [2,-3,-1,5,-4], K = 2
- 输出:13
- 解释:选择索引 (1, 4) ,然后 A 变为 [2,3,-1,5,4]。
提示:
- 1 <= A.length <= 10000
- 1 <= K <= 10000
- -100 <= A[i] <= 100
思路
要用贪心的方式去想解决方法
一个直观的想法是:
局部最优:让绝对值大的负数变为正数
全局最优:让数组元素的和最大
要实现上面的想法,需要先将数组进行排序(注意,此处排序包括负数,所以得自定义排序规则)
排完序之后就可以从小到大将负数反转为正数
但如果出现以下情况:(数组已经排序)
{-1, -2, -3, 5, 8}, K = 4 ---->{1, 2, 3, 5, 8}, K = 1
即将所有负数从小到大反转之后,K还有剩余
此时问题就变成了:在一个正整数数组中如何取反K次以获得最大数组元素和
那么这里又要制定新的贪心策略
局部最优:找到数组中数值最小的正整数进行反转(这样对整体影响最小)
全局最优:让数组元素的和最大
题外话:自定义sort排序规则
参考:https://www.cnblogs.com/Daniel-lmz/p/16452975.html
sort(iterator beg, iterator end, _Pred);  
// 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
// beg 开始迭代器
// end 结束迭代器
// _Pred 谓词(即cmp,排序的方式)
对[first****,last)(一定要注意这里的区间是左闭又开)区间内数据根据cmp的方式进行排序。也可以不写第三个参数,此时按默认排序,从小到大进行排序。
例子:自定义sort的排序规则(从大到小),默认是从小到大
static bool cmp(int a,int b){
     return b < a;
}
sort(a,a+n,cmp);
代码
步骤
依据上述思路可以总结出以下步骤:
1、先自定义排序规则,对含有负数的数组进行排序(自定义规则是:按照绝对值大小进行排序)
例子:{-3, -1, 0, 2}------->{-3, 2, -1, 0}
2、排好之后,遍历数组,从小到大将负数元素反转为正数,同时K--
3、如果负数已经被反转完,K仍有剩余,则不断反转当前数组中最小的正数,直到用完K
4、求出当前数组的和,返回
class Solution {
static bool cmp(int a, int b) {
    return abs(a) > abs(b);
}
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end(), cmp);//对含有负数的数组进行排序
        for(int i = 0; i < nums.size(); ++i){//遍历数组,从小到大将负数元素反转为正数
            if(nums[i] < 0 && k > 0){//第一处贪心
                nums[i] = -nums[i];
                k--;
            }
        }//如果负数已经被反转完,K仍有剩余,则不断反转当前数组中最小的正数(就是数组最后一个数),直到用完K
        if(k % 2 == 1){//第二处贪心
            nums[nums.size() - 1] *= -1;//只在k为奇数时取反,因为偶数取反还是正数,没必要进行操作
        }
        //求数组和
        int res = 0;
        for(int num : nums) res += num;
        return res;
    }
};
注意点
1、自定义sort的规则
在写cmp函数时,记得要用static修饰(参考本题题解)
2、反转亦有优化
当我们实现第二处贪心的逻辑时,需要对数组中的最小正数进行不断反转以消耗掉K值
此处是可以优化的
一个正数,翻转偶数次它还是正数
所以只需要在K为奇数的时候进行反转操作即可,这样可以省去偶数次反转操作带来的额外性能开支
3、for循环时别忘了可以使用增强for循环
【LeetCode贪心#05】K 次取反后最大化的数组和(自定义sort、二重贪心)的更多相关文章
- LeetCode竞赛题:K 次取反后最大化的数组和(给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。)
		给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次.(我们可以多次选择同一个索引 i.) 以这种方式修改数组后 ... 
- Leetcode 1005. K 次取反后最大化的数组和
		1005. K 次取反后最大化的数组和 显示英文描述 我的提交返回竞赛 用户通过次数377 用户尝试次数413 通过次数385 提交次数986 题目难度Easy 给定一个整数数组 A,我们只能用 ... 
- 1005.K次取反后最大化的数组和
		1005.K次取反后最大化的数组和 目录 1005.K次取反后最大化的数组和 题目 题解 排序+维护最小值min 题目 给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 ... 
- 【LeetCode】Maximize Sum Of Array After K Negations(K 次取反后最大化的数组和)
		这道题是LeetCode里的第1005道题. 题目描述: 给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次. ... 
- LeetCode1005 K次取反后最大化的数组和(贪心+Java简单排序)
		题目: 给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次.(我们可以多次选择同一个索引 i.) 以这种方式修 ... 
- [Swift]LeetCode1005. K 次取反后最大化的数组和 | Maximize Sum Of Array After K Negations
		Given an array A of integers, we must modify the array in the following way: we choose an i and repl ... 
- Java_按位与&,按位或,取反,左移,右移运算符
		//按位与运算& System.out.println(0&0);//0 System.out.println(0&1);//0 System.out.println(1&am ... 
- 第11.20节 Python 中正则表达式的扩展功能:后视断言、后视取反
		一. 引言 在<第11.19节 Python 中正则表达式的扩展功能:前视断言和前视取反>中老猿介绍了前视断言和前视取反,与二者对应的还有后视断言和后视取反. 二. (?<=-)后视 ... 
- 34988 Happy Reversal(二进制去取反)
		/* 题意:给多个二进制数,对某些数进行按位取反操作! 然后从中找到最大数和最小数,并输出他们的差值! 注意:所有的数都是整数,包括取反之后 思路:一个n为二进制数x,令tmp为n位全1!则 y=tm ... 
- C语言位运算符及作用:与、或、异或、取反、左移和右移
		一.& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0应用:(1)清零 若想对一个存储单元清零,即使其全部二进制位为0,只要找一个二进制数,其中各个位符合一下条件:原来的数 ... 
随机推荐
- [转帖]gdb调试常见命令详细总结(附示例操作)
			一.简介 通过gdb调试我们可以监控程序执行的每一个细节,包括变量的值.函数的调用过程.内存中数据.线程的调度等,从而发现隐藏的错误或者低效的代码,程序的调试过程主要有:单步执行,跳入函数,跳出函数, ... 
- [转帖]引人入胜,实战讲解“Java性能调优六大工具”之linux命令行工具
			Java性能调优六大工具之Linux命令行工具 为了能准确获得程序的性能信息,需要使用各种辅助工具.本章将着重介绍用于系统性能分析的各种工具.熟练掌握这些工具,对性能瓶颈定位和系统故障排查都很有帮助. ... 
- Linux无头模式使用mat分析dump的方法
			摘要 mat可以很好的进行jvm的内存dump的分析. 但是大部分服务器是没有GUI界面的. 而且就算是有GUI界面也很难直接使用. 但是随着jvm堆区越来越大. WindowsPC机器已经很难进行分 ... 
- 使用influxdb以及Grafana监控vCenter的操作步骤
			1. 下载安装介质 计划telegraf和influxdb 使用rpm包进行安装.Grafana使用docker容器方式安装 下载路径为: https://repos.influxdata.com/r ... 
- 【JS 逆向百例】某网站加速乐 Cookie 混淆逆向详解
			声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 逆向目标 目标:加速乐加密 ... 
- 【JS 逆向百例】医保局 SM2+SM4 国产加密算法实战
			关注微信公众号:K哥爬虫,QQ交流群:808574309,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途 ... 
- SqlSugar联表查询
			Join用法 语法糖1.2和3 在Where OrderBy GroupBy Select用法都一样的,他们区别就在JOIN的方式不一样,其它都一样 语法糖1 优点:好理解,5个表以内的联表非常爽,支 ... 
- PLSQL Developer汉语设置
			PLSQLQ Developer是由Oracle公司推出的数据库开发工具,具有很好的移植性和适应性.但是当我们安装完成Oracle11g PLSQL Developer工具后发现状态栏的显示是英文,对 ... 
- 【scikit-learn基础】--『回归模型评估』之损失分析
			分类模型评估中,通过各类损失(loss)函数的分析,可以衡量模型预测结果与真实值之间的差异.不同的损失函数可用于不同类型的分类问题,以便更好地评估模型的性能. 本篇将介绍分类模型评估中常用的几种损失计 ... 
- 关于 React 的作业(未完结)
			一.输出 Hello React 信息到网页的程序,非JSX的写法 代码实现如下: <!DOCTYPE html> <html lang="en"> < ... 
