代码随想录刷题03.14
贪心算法3
LeetCode题目
解题思路
1.本题的贪心思路:
1)单体个例:数组中的元素;
2)局部最优:
i)将数组按绝对值大小进行排序后,从前往后将负值变为正值;
ii)若k值仍然有多,则将最后一个数值反复变正负;
2.比较函数cmp的使用:
1)比较函数在其他函数操作中(比如sort函数)像是一个开关,操作函数的操作要满足这个开关条件;
2)比较函数前最好加上static:
在定义比较函数时,将其定义为static函数是一种常见的做法,但并不是必须的。在大多数情况下,将比较函数定义为static函数有以下几个好处:
a)避免命名冲突:将比较函数定义为static函数,可以避免与其他函数命名冲突,特别是在使用命名空间的情况下;
b)减小函数调用的开销:将比较函数定义为static函数,可以减小函数调用的开销,因为static函数不需要通过类的实例来调用,可以直接通过类名来调用。
c)更好的封装性:将比较函数定义为static函数,可以将其作为类的私有成员函数,从而提高类的封装性。
若本题不定义为static函数,则在使用sort函数操作时,应改为
sort(nums.begin(),nums.end(),[this](int a, int b){return cmp(a, b);});
代码过程
/*class Solution {
public:
static bool cmp(int a,int b){
return abs(a)>abs(b);
}
int result=0;
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]*=-1;
k--;
}
result+=nums[i];
}
if(k>0){
if(k%2)result=result-2*nums[nums.size()-1];
}
return result;
}
};*/
class Solution {
public:
bool cmp(int a,int b){
return abs(a)>abs(b);
}
int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(),nums.end(),[this](int a, int b){return cmp(a, b);});
int result=0;
for(int i=0;i<nums.size();i++)
{
if(nums[i]<0&&k>0){
nums[i]*=-1;
k--;
}
result+=nums[i];
}
if(k>0){
if(k%2)result=result-2*nums[nums.size()-1];
}
return result;
}
};
LeetCode题目
解题思路
1.贪心算法的精髓:使用一次遍历即可得到需要的结果,因此,在一次遍历中,要做到局部最优。
2.本题的贪心思路:
1)单体个例:加油站元素;
2)局部最优:当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行–>全局最优:找到可以跑一圈的起始位置。
代码过程
class Solution {
public:
int curoil=0;
int totaloil=0;
int startindex=0;
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
for(int i=0;i<gas.size();i++)
{
curoil+=gas[i]-cost[i];
totaloil+=gas[i]-cost[i];
if(curoil<0){
startindex=i+1;
curoil=0;
}
}
if(totaloil<0)return -1;
return startindex;
}
};
LeetCode题目
解题思路
1.贪心算法的精髓:如何一次遍历得到优解;
2.本题思路:
1)先确定右边评分大于左边的情况(也就是从前向后遍历)
此时局部最优:只要右边评分比左边大,右边的孩子就多一个糖果。全局最优:相邻的孩子中,评分高的右孩子获得比左边孩子更多的糖果;
2)再确定左孩子大于右孩子的情况(从后向前遍历)
局部最优:取只要左边评分比左边大,左边的孩子就多一个糖果。全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。
3)最后,取两次分发结果中较大的那一个作为最终结果。
代码过程
class Solution {
public:
int candy(vector<int>& ratings) {
vector<int>rightcandy(ratings.size(),1);
vector<int>leftcandy(ratings.size(),1);
vector<int>candy(ratings.size(),1);
int sum=0;
for(int i=1;i<ratings.size();i++)
{
if(ratings[i]>ratings[i-1]){
rightcandy[i]=rightcandy[i-1]+1;
}
}
for(int j=ratings.size()-2;j>=0;j--)
{
if(ratings[j]>ratings[j+1]){
leftcandy[j]=leftcandy[j+1]+1;
}
}
for(int k=0;k<ratings.size();k++)
{
candy[k]=rightcandy[k]>leftcandy[k]?rightcandy[k]:leftcandy[k];
sum+=candy[k];
}
return sum;
}
};