Table of contents
LeeCode 1005. Maximized array sum after K inversions
LeeCode 134. Gas Station
LeeCode 135. Handing out candy
LeeCode 1005. Maximized array sum after K inversions
1005. Array Sum Maximized After K Inversions - LeetCode
Ideas:
Local optimum: only find the positive integer with the smallest value for inversion, and the sum of the current values can reach the maximum. Global optimum: the sum of the entire array reaches the maximum.
class Solution {
static bool cmp(int a, int b) {
return abs(a) > abs(b);
}
public:
int largestSumAfterKNegations(vector<int>& nums, int k) {
//将数组按照绝对值大小从大到小排序
sort(nums.begin(), nums.end(), cmp);
//从前向后遍历,遇到负数将其变为正数,同时k--
for (int i = 0; i < nums.size(); i++) {
if (nums[i] < 0 && k > 0) {
nums[i] *= -1;
k--;
}
}
//如果k还大于0,转变数值最小的元素
if (k % 2 == 1) nums[nums.size() - 1] *= -1;
//求和
int result = 0;
for (int a : nums) result += a;
return result;
}
};
Time complexity: O(n log n) Space complexity: O(1)
LeeCode 134. Gas Station
Greedy Algorithm 1: Carry out greedy algorithm directly from the whole world, divided into the following situations:
-
Situation 1: If the sum of gas is less than the sum of cost, no matter where you start from, you will not be able to complete a lap;
-
Situation 2: rest[i] = gas[i] - cost[i] is the remaining gas at one station, and i starts to calculate and accumulate from 0 to the last station. If there is no negative number in the accumulation, it means that 0 is the starting point;
-
Situation 3: If the accumulated minimum value is a negative number, the car will start from a non-zero node, from the back to the front, to see which node can fill up the negative number, and the node that can fill up the negative number is the starting node.
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int curSum = 0;
int min = INT_MAX;
for (int i = 0; i < gas.size(); i++) {
int rest = gas[i] - cost[i];
curSum += rest;
if (curSum < min) min = curSum;
}
if (curSum < 0) return -1;
if (min >= 0) return 0;
for (int i = gas.size() - 1; i >= 0; i--) {
int rest = gas[i] - cost[i];
min += rest;
if (min >= 0) return i;
}
return -1;
}
};
Time complexity: O(n) Space complexity: O(1)
Greedy Algorithm 2: Local Optimum: Once the sum curSum of the current accumulated rest[i] is less than 0, the starting position must be at least i + 1. Global Optimum: Find a starting position that can run around.
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];
//当前累加 rest[i] 和 curSum 小于0时,起始位置更新为i + 1
if (curSum < 0) {
start = i + 1;
curSum = 0;
}
}
if (totalSum < 0) return -1;
return start;
}
};
Time complexity: O(n) Space complexity: O(1)
LeeCode 135. Handing out candy
135. Hand out candy - LeetCode
Ideas:
Apply the greedy strategy twice: traversing from left to right, only comparing the case where the child on the right has a higher score than the left; traversing from right to left, only comparing the case where the child on the left has a higher score than the right. The global optimum is derived from the local optimum, that is, among adjacent children, children with high scores get more candies.
class Solution {
public:
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;
}
};
Time complexity: O(n) Space complexity: O(n)