1005 K次取反后最大化的数组和
题目链接:k次取反后最大化的数组和
思路
这道题目刚拿到手,就像的是找到k个最小的数,然后取反求和即可。但是这样却忽略了几种情况:
- 一个数可以重复取反
- 0是绝对值最小的数
因此我们应该按照绝对值的大小对该数组进行排序,然后先对里面所有的负数取反,如果有剩余的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] *= -1;
k--;
}
}
if (k % 2 == 1) nums[nums.size() - 1] *= -1; // 第三步
int result = 0;
for (int a : nums) result += a; // 第四步
return result;
}
};
134 加油站
题目链接:加油站
思路
这道题目参考解析,发现还是容易理解的。
- 如果加油站的总油量小于
cost
的总油量,那么汽车无论如何都开不了一圈。 - 这道题目我们要寻找的是起始的加油站位置,那就是说从这个位置开始,后面的剩余油量都要大于等于0,如果出现小于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){
start = i+1;
curSum = 0;
}
}
if(totalSum < 0){
return -1;
}
return start;
}
};
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] = max(candy[i+1]+1, candy[i]);
}
}
int res=0;
for(int i=0; i<candy.size(); i++){
res+=candy[i];
}
return res;
}
};
参考链接
- https://programmercarl.com/0135.%E5%88%86%E5%8F%91%E7%B3%96%E6%9E%9C.html#%E6%80%9D%E8%B7%AF