贪心算法
1005. K 次取反后最大化的数组和
题意:给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。
重复这个过程恰好 k 次。可以多次选择同一个下标 i 。以这种方式修改数组后,返回数组 可能的最大和 。
示例:
思路:本题的思路主要在两次排序,第一次排序,是为了消耗k的次数,将局部最大负数变为正数;第二次排序,是为了消耗掉多余的k,将最小影响全局元素进行改变,直到所有k消耗完,主打的就是性价比极高的操作,最终得出数组的最大值
C++代码:
int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();i++)//先将可以变成正数的负数变成正数
{
if(nums[i]<0&&k!=0)
{
nums[i]*=-1;
k--;
}
}
sort(nums.begin(),nums.end());//再次给出排序
while(k--)//如果还没到达改变次数,就改变影响最小的元素
{
nums[0]*=-1;
}
int count=0;
for(auto e:nums)//累加即可
{
count+=e;
}
return count;
}
134. 加油站
题意:在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。
示例:
思路:我们给出三个变量:全局剩余油量total,局部剩余油量parttotal和起始位置begin,大体分为两种情况:total小于0时,说明无论如何都跑不了一圈;total大于等于0时,说明可以跑完一圈,此时需要从0开始,进行剩余油量的累加,当parthtotal小于0时,说明从起始位置到i的这部分是一定不可能走完的,因此起始位置变为i+1,parthtotal重置,重新开始累加
C++代码:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int total=0,partTotal=0,begin=0;//表示:一圈的油量,局部油量,起始位置
for(int i=0;i<gas.size();i++)
{
total+=gas[i]-cost[i];
partTotal+=gas[i]-cost[i];
if(partTotal<0)//当局部油量出现小于0的情况,就说明从begin位置出发不正确,此时起始位置就可以变为i+1,因为之前的已经测试过了,不能到达i
{
begin=i+1;
partTotal=0;
}
}
if(total<0)//还是需要检验以下总体剩余油量必须不为负数
{
return -1;
}
return begin;
}
135. 分发糖果
题意:n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到 1 个糖果。
- 相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
示例:
思路:本题我们,先创建一个数组用于存储孩子可以获得的最少糖果数,初始化为1,然后两次遍历完成:正序遍历和倒序遍历
- 正序遍历:先对正序的相邻糖果进行累加
- 倒序遍历:对倒序的相邻糖果进行累加,此时必须满足两个条件才能进行糖果的调整:1.前一个小孩的评分必须大于后一个小孩的评分 2.前一个小孩得到的糖果必须小于后一个小孩得到的糖果
只有满足这两个条件,倒序遍历时,孩子的糖果才能增加
C++代码:
int candy(vector<int>& ratings) {
vector<int> dp(ratings.size(), 1);
for (int i = 1; i<ratings.size(); i++)//先正序遍历,将正序中遇到的评分高的孩子糖果数累加1
{
if (ratings[i]>ratings[i - 1])
{
dp[i] += dp[i - 1];
}
}
for (int i = ratings.size() - 1; i>0; i--)//倒序遍历,此时改变糖果数需要满足两个条件
{
if (ratings[i - 1]>ratings[i]&&dp[i-1]<=dp[i])
{
dp[i - 1] += dp[i]-dp[i-1]+1;//添加的糖果数必须最小达标
}
}
int count = 0;//最小糖果总数
for (auto e : dp)
{
count += e;
}
return count;
}