前言
LeetCode题目:LeetCode 1005、134、135
Takeaway:贪心算法,分部分的贪心解法。
一、1005
挺简单的一道题,贪心逻辑分为两部分,第一部分是反转负数,第二部分是负数没了之后,就一直反转最小的数。
class Solution {
public:
int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
for(int i=0;i<nums.size();i++){
if(nums[i]<=0 && k>0){
nums[i] = -nums[i];
k--;
}
}
sort(nums.begin(), nums.end());
while(k>0){
nums[0] = -nums[0];
k--;
}
int ans = 0;
for(int i=0;i<nums.size();i++){
ans += nums[i];
}
return ans;
}
};
二、134
加油问题,这题的贪心逻辑是存油量为负数的时候,就从下一个点开始走。
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
vector<int> rest;
for(int i=0; i<gas.size(); i++){
rest.push_back(gas[i]-cost[i]);
}
int curSum = 0;
int totalSum = 0;
int ans = 0;
//curSum表示当前的综总和是否>0,大于说明还能跑
for(int i=0; i<gas.size(); i++){
curSum += rest[i];
totalSum += rest[i];
if(curSum < 0){
ans = i+1;
curSum = 0;
}
}
// 说明总和小于0,从哪跑都不够
if(totalSum < 0){
return -1;
}
return ans;
}
};
三、135
发糖问题,这题的贪心逻辑要分两步走,先从左到右,再从右到左,每次求局部最优合并为整体最优,第二次把第一次覆盖。
class Solution {
public:
int candy(vector<int>& ratings) {
vector<int> candy(ratings.size(), 1);
int ans=0;
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], candy[i+1]+1);
}
}
for(int i=0;i<candy.size();i++){
ans += candy[i];
}
return ans;
}
};
总结
贪心算法,分部分的贪心解法。