【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,只要找一个二进制数,其中各个位符合一下条件:原来的数 ...
随机推荐
- [转帖]龙芯3A5000评测 国产自主指令集架构实战
https://tieba.baidu.com/p/8297036384?pid=147031768904&cid=#147031768904 芯片,是世界一大难题,很多人难以想象电子硬件 ...
- [转帖]一个故事看懂CPU的SIMD技术
https://www.cnblogs.com/xuanyuan/p/16048303.html 好久不见,我叫阿Q,是CPU一号车间的员工.我所在的CPU有8个车间,也就是8个核心,咱们每个核心都可 ...
- 【转贴】java 进程运行状态图解
java 进程运行状态图解 原文博客地址 https://www.cnblogs.com/GooPolaris/p/8079490.html java中进程的状态有 6 种: NEW(新建).RU ...
- 基于华为fusionstorage的块存储CSI
承接上文,块存储的CSI要比对象存储复杂一些,但总的处理逻辑还是一致的.下面以华为fusionstorage的CSI为例进行介绍,该插件支持了多个后端存储,如fusionstorage和oceanst ...
- IdentityServer4 系列文章01---密码授权模式
IdentityServer4实现.Net Core API接口权限认证(快速入门) 什么是IdentityServer4 官方解释:IdentityServer4是基于ASP.NET Core实 ...
- 手撕Vuex-实现共享数据
经过上一篇章介绍,完成了添加全局 $store,接下来就是实现共享数据的功能. 在 Vuex 中,共享数据是通过 state 来实现的,所以我们需要在 Nuex.js 文件中实现 state 的功能. ...
- 解决SystemExit: 2,args = parser.parse_args() 的问题,
报错: File "/home/barry/PycharmProjects/EEPC/detect.py", line 283, in parse_opt opt = parser ...
- 7.5 通过API判断进程状态
进程状态的判断包括验证进程是否存在,实现方法是通过枚举系统内的所有进程信息,并将该进程名通过CharLowerBuff转换为小写,当转换为小写模式后则就可以通过使用strcmp函数对比,如果发现继承存 ...
- C/C++ MinHook 库的使用技巧
在上面的各种Hook挂钩方式中,我们都是在手写封装代码,但这样的方式并不高效,真正的生产环境中我们必须使用现成的Hook库,常用的Hook库有免费开源的MinHook和商业的Detours Hook, ...
- centos离线安装mongodb-database-tools
mongodb-database-tools是MongoDB数据库工具的命令行的工具,用于工作与MongoDB部署.可以使用mongodump和mongoimport很方便的导入导出备份数据. 该数据 ...