大纲
● 1005.K次取反后最大化的数组和
● 134. 加油站
● 135. 分发糖果
1005.K次取反后最大化的数组和
题目:
本题的思路是对数组按照绝对值从小到大排序后,将排序后数组小于0的部分先进行反转,如果k还有,那么将绝对值最小值【nums[0]】进行反复反转,消耗完剩下的反转次数,则可以最大化数组和
// 排序函数,按照绝对值从小到大排序
bool _compareAbs(int a, int b) {
return abs(a) < abs(b);
}
int kthReveaseArray(vector<int>& nums, int k) {
// 按照绝对值排序
sort(nums.begin(), nums.end(), _compareAbs);
int sum = 0;
for (int i = nums.size() - 1; i >= 0; --i) {
if (nums[i] < 0 && k-- > 0)
nums[i] = -nums[i];
}
// k还有那么反复反转绝对值最小的值
if (k % 2 == 1) nums[0] = -nums[0];
for (int i = 0; i < nums.size(); ++i) {
sum += nums[i];
}
return sum;
}
134. 加油站
题目:134. 加油站
本题比较难想到,需要遍历汽油数组,统计**走到当前节点总共剩下的汽油数量 totalLeft 和从start开始时剩下的汽油数量singleLeft **,如果singleLeft 小于0了,那么说明以start开始的节点是行不通的,已经耗完了汽油。遍历完汽油数组后,如果totalLeft 还大于0,则返回start作为起点
int getGasCost(vector<int>& gas, vector<int>& cost) {
int start = 0, totalLeft = 0, singleLeft = 0;
for (int i = 0; i < gas.size(); ++i) {
singleLeft += gas[i] - cost[i];
totalLeft += gas[i] - cost[i];
if (singleLeft < 0) {
start = i + 1;
singleLeft = 0;
}
}
if (totalLeft >= 0) return start;
return -1;
}
135. 分发糖果
题目:135. 分发糖果
本题看看解题参考吧
int candy(vector<int>& ratings) {
vector<int> candyVec(ratings.size(), 1);
// 从前向后
for (int i = 1; i < ratings.size(); i++) {
if (ratings[i] > ratings[i - 1]) candyVec[i] = candyVec[i - 1] + 1;
}
// 从后向前
for (int i = ratings.size() - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1] ) {
candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1);
}
}
// 统计结果
int result = 0;
for (int i = 0; i < candyVec.size(); i++) result += candyVec[i];
return result;
}