1005.K次取反后最大化的数组和
题目描述
题目链接:力扣1005.K次取反后最大化的数组和
给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:
- 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。
重复这个过程恰好 k 次。可以多次选择同一个下标 i 。
以这种方式修改数组后,返回数组 可能的最大和 。
思路
小堆优先队列,不断取出存入,重复k次后求和。
代码实现
class Solution {
public:
int largestSumAfterKNegations(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<int>> priQue;
for(int num : nums) priQue.push(num);
while(k--) {
int temp = priQue.top();
priQue.pop();
priQue.push(-temp);
}
int res = 0;
while(!priQue.empty()) {
res += priQue.top();
priQue.pop();
}
return res;
}
};
134.加油站
题目描述
题目链接:力扣134.加油站
在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。
思路
首先检查第 0 个加油站,并试图判断能否环绕一周;如果不能,就从第一个无法到达的加油站开始继续检查。
代码实现
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int n = gas.size();
int i = 0;
while (i < n) {
int sumOfGas = 0, sumOfCost = 0;
int cnt = 0;
while (cnt < n) {
int j = (i + cnt) % n;
sumOfGas += gas[j];
sumOfCost += cost[j];
if (sumOfCost > sumOfGas) {
break;
}
cnt++;
}
if (cnt == n) {
return i;
} else {
i = i + cnt + 1;
}
}
return -1;
}
};
135.分发糖果
题目描述
题目链接:力扣135.分发糖果
n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到 1 个糖果。
- 相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
思路
分别从左边和右边遍历一边孩子的评分,维护两个数组:
- 第一个数组:从左向右遍历孩子评分,如果右边孩子评分大于相邻的左边孩子评分,则糖果数加1;若小于则给1个。
- 第二个数组:再从右向左遍历孩子评分,如果左边孩子评分大于相邻的右边孩子的评分,则糖果数加1;若小于则给1个。
- 最后取两个数组每个位置上的较大值即可。
代码实现
class Solution {
public:
int candy(vector<int>& ratings) {
int n = ratings.size();
vector<int > l(n), r(n);
l[0] = 1;
r[n-1] = 1;
for(int i=1; i<n; i++){
l[i] = ratings[i] > ratings[i-1] ? l[i-1] + 1 : 1;
}
for(int i=n-2; i>=0; i--){
r[i] = ratings[i] > ratings[i+1] ? r[i+1] + 1 : 1;
}
int res = 0;
for(int i=0; i<n; i++){
res += max(l[i], r[i]);
}
return res;
}
};