目录
前言:
1005. K 次取反后最大化的数组和 - 力扣(LeetCode)
134. 加油站 - 力扣(LeetCode)
总结:
前言:
今天随机刷题,不对题型做具体的要求
1005. K 次取反后最大化的数组和 - 力扣(LeetCode)
给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:
选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。
重复这个过程恰好 k 次。可以多次选择同一个下标 i 。
以这种方式修改数组后,返回数组 可能的最大和 。
解题思路:要想最终的得到的数组和最大,我们就不要想的太复杂,很多人会想:
- 1.k值足够所有的负数取正,并且有剩余,此时全部数都是正的,那么我们想要得到最大值就不断给最小值取反就可以了,直到K值用光。这也就可以得到所有的负数和。
- 2.K值不够所有的负数取反,那么我们只需要让所有更小的负数取反就好了(更小的负数取反之后结果更大),这也就可以得到最大的数组元素和。
- 3.如果数组中根本就没有负数,那么就属于我们情况1的子情况,给都是正数的集合取反求最大值,只需要一直用最小的值取反就好了
很多人思考到这里就没有继续思考了,导致写出来的代码太过于繁杂,情况判断复杂,但我们可以提炼这三种情况,实际上就是一直不断的给整个数组中最小的值取反
当有负数的时候,给最小的值(负数)取反实际就是为了得到较大正数,我们再每一次取反之后都排序,确保第一位始终都是最小的数字。
当没有负数的时候,我们就一直对第一位进行取反排序,这一过程始终操作的都是最小数。
也就是说整个题就是一个贪心思路解法:如果想要得到数组元素之和最大值,就要一直对数组的最小值进行取反,当最小值是负数的时候,我们给最小值取反相当于尽可能的获取最大负数取反值,当最小值是整数的时候,就尽可能保证这个数字取反之后成为负数对元素和的最大值影响最小。
解法1:
class Solution {
public:
int largestSumAfterKNegations(vector<int>& nums, int k) {
for(int i=0;i<k;i++)
{
sort(nums.begin(),nums.end());
nums[0]=-nums[0];
}
int sum=0;
for(int a :nums)
{
sum=sum+a;
}
return sum;
}
};
134. 加油站 - 力扣(LeetCode)
在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。
其实本题我们也可以用贪心算法的思路来做,也就是说:每一个站都有自己的增油量和耗油量,如果说每一个站的耗油量和增油量做差下来的值总和小于0,那么肯定是无法完成整个环的,如果是大于0,我们对这个数组进行遍历,寻找从哪里加起来不会让值总和小于等于0就可以了。
解得:
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int n = gas.size();
int start = 0;
int total = 0;//起点开始到当前加油站的总汽油量减去总消耗量。
int tank = 0;//剩余油量
for (int i = 0; i < n; i++) {
tank += gas[i] - cost[i];
total += gas[i] - cost[i];
if (tank < 0) {
start = i + 1;
tank = 0;
}
}
return total >= 0 ? start : -1;
}
};
总结:
今天刷了两道贪心算法的题目,收获很大。
如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!