学习目标:
- 1005.K次取反后最大化的数组和
- 134. 加油站
- 135. 分发糖果
学习内容:
1005.K次取反后最大化的数组和
//方法1
class Solution {
static bool cmp(int a, int b) {
if(abs(a)> abs(b))
return true;
else
return false;
}
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--;
}
}
//经过上一步后nums中所有负数已经变为正数,而使用的绝对值排序,所以最后一个是最小的正数
if(k>0 && k%2!=0) nums[nums.size()-1] = nums[nums.size()-1] * (-1);
int sum = 0;
for(int i=0 ; i<nums.size();i++)
{
sum+=nums[i];
}
return sum;
}
};
排序算法
sort函数需要调用#include <algorithm>
库,自定义排序的时候定义static bool cmp.return true为降序排列,return false为升序排列。
错误以及注意事项
- 这个方法真滴很巧妙。首先有限处理所有的负数,当所有的负数处理完后。找最小的正数反复折磨,但是由于是按照绝对值排序,所以不需要反复排序,直接取最后一个元素即可。
134. 加油站
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int totalsum = 0;
int cursum = 0;
int startIndex = 0;
for(int i = 0;i<gas.size();i++)
{
totalsum +=gas[i]-cost[i];
}
if(totalsum<0)
return -1;
for(int i = 0;i<gas.size();i++){
cursum += gas[i]-cost[i];
if(cursum<0){
startIndex = i+1;
cursum = 0;
}
}
return startIndex;
}
};
错误以及注意事项
- 只学了方法二,方法一还没有搞明白。以及并不熟练。需要再做。
方法1:
直接从全局进行贪心选择,情况如下:
情况一:如果gas的总和小于cost总和,那么无论从哪里出发,一定是跑不了一圈的
情况二:rest[i] = gas[i]-cost[i]为一天剩下的油,i从0开始计算累加到最后一站,如果累加没有出现负数,说明从0出发,油就没有断过,那么0就是起点。
情况三:如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点能把这个负数填平,能把这个负数填平的节点就是出发节点。
方法2:
i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum。
135. 分发糖果
class Solution {
public:
int candy(vector<int>& ratings) {
vector<int> candy(ratings.size(),1);
for(int i = 1;i<ratings.size();i++)
{
if(ratings[i]>ratings[i-1])
candy[i] = candy[i-1] +1;
}
for(int i = ratings.size()-2;i>=0;i--)
{
if(ratings[i]>ratings[i+1] && candy[i]<=candy[i+1])
candy[i]=candy[i+1]+1;
}
int result=0;
for(int i=0;i<candy.size();i++)
{
result += candy[i];
}
return result;
}
};
错误以及注意事项
- 第二个循环如果不是从后往前,而是继续从前往后,就会:
在这个问题中,第二个循环的目的是为了处理评分降低但糖果数量不够的情况。如果我们从前往后遍历,我们可能会在处理某个位置时,已经将其分配的糖果数量增加了,但是后面的位置的糖果数量可能已经确定,我们不能再更改它们。
因此,从后往前遍历确保了我们先处理评分较高的孩子,从而避免了在后面更改分配的糖果数量。这样可以确保我们在更新糖果数量时不会破坏前面的分配情况。
学习时间:
2024.2.26-2.27 11:25 焦虑。下周一周二面试。