1005.K次取反后最大化的数组和
思路还是比较明确的:先将最小的负数尽可能的转化为正数,并在之后判断几种可能出现的情况:
1、反转次数k有剩余,若是奇数,则把最小的数反转,若是偶数,则返回和
2、反转次数k无剩余,则直接返回。
这就要求了对于数组的排序有了一定的要求:即对数组进行绝对值排序:
static bool cmp(int nums1,int nums2){
return abs(nums1)>abs(nums2);
}
sort(nums.begin(),nums.end(),cmp);
同时本题需要注意,数组单个位置取反应该用*=-1,不然会报错。
剩下的就是简单的判断、反转,求和了。
134. 加油站
思考一阵之后对于本题的想法主要是求两个数组的对位差,并计算对位差的累加:
for(int i=0;i<gas.size();i++){
int temp=gas[i]-cost[i];
cur+=temp;//对位差的累加
if(cur<min){
min=cur;//对位差累加的最低点
}
}
同时可能出现三种情况:
1、累加和小于0:根本跑不到,返回-1;
2、累加和大于零,且累加的最低点大于零,从零开始就可以跑完,全程油充足。
3、累加和大于零,但是累加的最低点小于零,此时需要从后往前(因为车是沿着数组从前往后跑,并逐个计量的)累加判断什么时候对位差的和能覆盖住累加最低点的负值,此时便可以选为开始节点
if(cur<0)return -1;
if(min>=0)return 0;
for(int i=gas.size()-1;i>=0;i--){
int res=gas[i]-cost[i];
min+=res;
if(min>=0)return i;
}
135. 分发糖果
本体的思路十分新颖,由于每两个相邻孩子不同成绩就要成绩高的比成绩低的多的糖果所以对于高分的在左边以及高分的在右侧两种情况,这时,就需要转换思路不再是一个一个的从左到右每个孩子成绩左右比较判断,而是先从左到右挨个比较一次,再从右到左挨个比较一次,第一次只要右侧比左边大,就糖果加一,
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+1]<ratings[i]){
candy[i]=max(candy[i+1]+1,candy[i]);
}
}
整体来说还是很有难度、很难理解的。