1005.K次取反后最大化的数组和
这道题我的思路就是,首先按照绝对值大小,依次把最小的负数变成正数,(第一个贪心);接着,把最小的绝对值的数变化k次,这样能保证和最大,最后再求和,但是我写代码时不太顺畅,参考了代码随想录,最终详细代码如下:
class Solution {
public:
static bool cmp(int a, int b)
{
return abs(a)>abs(b);
}
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--;
}
}
//变换绝对值最小的数
if(k>0&&k%2==1) nums[nums.size()-1]*=(-1);
//求和;
int sum =0;
for(int num:nums)
{
sum+=num;
}
return sum;
}
};
134. 加油站
本题思路比较巧妙,利用的是剩余油量的逻辑,如果剩余油量的累加和小于0,说明当前走不到,下一个站点,所以要从下一站点继续尝试能否走完,巧妙地利用总油量剩余累加及当前油量剩余累加,确定是否能跑完一圈。
详细代码如下:
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int cursum = 0;
int totalsum = 0;
int start = 0;
for(int i=0;i<gas.size();i++)
{
cursum+=gas[i]-cost[i]; //剩余油量的累加和
totalsum+=gas[i]-cost[i];
if(cursum<0)
{
cursum=0;
start = i+1;
}
}
if(totalsum<0) return -1;
return start;
}
};
135. 分发糖果
本题涉及到一个思想,就是想处理好一边再处理另一边,不要两边想着一起兼顾:
详细代码如下:
class Solution {
public:
int candy(vector<int>& ratings) {
//先顾一边,再顾另一边
vector<int> res(ratings.size(),1);
//保证右边比左边大的比左边多
for(int i = 1;i<ratings.size();i++)
{
if(ratings[i]>ratings[i-1]) res[i] = res[i-1]+1;
}
//保证左边比右边大
for(int i=ratings.size()-2;i>=0;i--)
{
if(ratings[i]>ratings[i+1]) res[i] = max(res[i], res[i+1]+1); //最值
}
int sum=0;
for(int r:res)
{
sum+=r;
}
return sum;
}
};