代码随想录——贪心9.K次取反后最大化的数组和 && std::sort函数的第三个参数说明
1.代码随想录-逆波兰式、滑动窗口最大值2.代码随想录-栈与队列-有效的括号(括号匹配)3.代码随想录——栈与队列8-前K个高频元素4.二叉树的递归遍历和迭代遍历5.代码随想录——二叉树-11.完全二叉树的节点个数6.代码随想录——二叉树-12.平衡二叉树7.代码随想录——二叉树17-路径总和8.代码随想录——二叉树19.最大二叉树9.代码随想录——二叉树21、合并二叉树(附:递归算法复杂度分析)10.代码随想录——二叉树23、验证二叉搜索树11.代码随想录——25二叉搜索树的最小绝对值差(递归遍历如何记录前后两个指针)12.代码随想录——25.二叉搜索树中的众数13.代码随想录——26、二叉(搜索)树的最近公共祖先14.代码随想录——回溯8、组合总和II15.代码随想录——回溯9.分割回文串16.代码随想录——回溯19重新安排行程17.代码随想录——回溯 N皇后18.代码随想录——贪心8.跳跃游戏II
19.代码随想录——贪心9.K次取反后最大化的数组和 && std::sort函数的第三个参数说明
20.代码随想录——贪心13.分发糖果21.代码随想录——贪心算法:根据身高重建队列 & Vector原理22.代码随想录——贪心算法22单调递增的数字23.代码随想录——贪心23监控二叉树24.代码随想录——动态规划5.周总结25.代码随想录——动态规划9不同的二叉搜索树26.代码随想录——动态规划01背包27.代码随想录——动态规划13.分割等和子集28.代码随想录——动态规划14最后一块石头的重量II(01背包)29.动态规划——dp的含义归类(完全背包和01背包区别)30.动态规划——26单词拆分31.代码随想录——动态规划背包问题总结32.代码随想录——动态规划31打家劫舍III(树状DP)33.代码随想录——动态规划、股票问题34.代码随想录——单调栈35.回溯总结思路
第一想法是排序后先把负数取反消耗k,但是这样有个问题:k还剩余,并且所有元素都为正数的时候,不好找最小值去消耗k
故采用绝对值逆序排序,这样就算全是正数了,它也是单调递减的,最小值就是size()-1位置的元素
static bool cmp(int a,int b){
return abs(a) > abs(b);
}
int largestSumAfterKNegations(vector<int>& nums, int k) {
//第一想法是排序后先把负数取反消耗k,但是这样有个问题:k还剩余,并且所有元素都为正数的时候,不好找最小值去消耗k
//故采用绝对值逆序排序,这样就算全是正数了,它也是单调递减的,最小值就是size()-1位置的元素
sort(nums.begin(),nums.end(),cmp);
int sum = 0;
for(int i=0;i<nums.size();i++){
if(nums[i] < 0 && k > 0){
nums[i] = -nums[i];
k--;
}
}
//k如果大于0——偶数不管,奇数让绝对值最小的取反
if(k % 2 != 0)nums[nums.size()-1] *= -1;
for(int a:nums)sum += a;
return sum;
}
sort函数的第三个参数
如果cmp函数不是static会编译报错:
原因分析
- 成员函数的调用需要对象
默认情况下,class 中的普通成员函数(非 static)隐式地绑定到某个对象实例(this 指针)。也就是说,成员函数在调用时必须通过类的对象来调用,例如:
Solution sol;
sol.cmp(a, b);
- std::sort 的要求
std::sort 接受一个可调用对象(如函数指针或函数对象)作为第三个参数,用于比较两个元素的大小关系。这个比较函数必须是普通的函数,或者是一个 static 函数,因为:
- 普通的成员函数需要一个对象实例(this 指针)才能调用,而 std::sort 只是调用比较函数来比较两个值,它不知道也不管理 this 指针。
- 静态成员函数 (static) 不依赖 this 指针,可以直接通过类名调用,不需要绑定到具体对象上。
如果 cmp 不是 static 的,编译器会报错,因为 std::sort 无法将你的非静态成员函数作为比较函数使用。
- static 的作用
static 修饰的成员函数是属于类本身的,而不是某个对象实例的。这意味着:
- 它不需要依赖对象实例(this 指针)。
- 可以像普通函数一样直接使用。
- 适合像这里这种情况,作为回调函数传递给 std::sort。
解决方案
保持 static 你的代码正确地将 cmp 定义为 static,这是最简单和直接的解决方式:
static bool cmp(int a, int b) {
return abs(a) > abs(b);
}
使用外部普通函数 如果你不想使用 static,可以将 cmp 定义为类外的普通函数:
bool cmp(int a, int b) {
return abs(a) > abs(b);
}
class Solution {
public:
int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(), nums.end(), cmp);
// ... your logic ...
}
};
使用 lambda 表达式 如果不需要重复使用 cmp,可以直接在调用 std::sort 时使用 lambda 表达式:
sort(nums.begin(), nums.end(), [](int a, int b) {
return abs(a) > abs(b);
});
总结
你在这里需要 static 的原因是普通成员函数依赖对象实例,而 std::sort 无法处理这种依赖。如果不想使用 static,可以考虑用普通函数或 lambda 表达式来代替。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现