LeetCode DAY29(1005. Maximize Sum Of Array After K Negations&134. Gas Station&135. Candy)

Preface

This is a new day to continue my Greedy Algorithm journey.
Learn something new and keep reviewing what I learnt before.

1. Maximize Sum Of Array After K Negations

LeetCode Link: 1005. Maximize Sum Of Array After K Negations
Given an integer array nums and an integer k, modify the array in the following way:

choose an index i and replace nums[i] with -nums[i].
You should apply this process exactly k times. You may choose the same index i multiple times.

Return the largest possible sum of the array after modifying it in this way.

Example 1:

Input: nums = [4,2,3], k = 1
Output: 5
Explanation: Choose index 1 and nums becomes [4,-2,3].
Example 2:

Input: nums = [3,-1,0,2], k = 3
Output: 6
Explanation: Choose indices (1, 2, 2) and nums becomes [3,1,0,2].
Example 3:

Input: nums = [2,-3,-1,5,-4], k = 2
Output: 13
Explanation: Choose indices (1, 4) and nums becomes [2,3,-1,5,4].

Constraints:

1 <= nums.length <= 104
-100 <= nums[i] <= 100
1 <= k <= 104

Analysis and Solution

Greedy Algorithm

LeetCode C++ as followings Greedy Algorithm

class Solution {
static bool cmp(int a, int b) {
    return abs(a) > abs(b);
}
public:
    int largestSumAfterKNegations(vector<int>& A, int K) {
        sort(A.begin(), A.end(), cmp);       // Sort the array from big to small according to the absolute value, pay attention to the size of the absolute value
        for (int i = 0; i < A.size(); i++) { // Traversing from front to back, when encountering a negative number, turn it into a positive number, and K--
            if (A[i] < 0 && K > 0) {
                A[i] *= -1;
                K--;
            }
        }
        if (K % 2 == 1) A[A.size() - 1] *= -1; // If K is still greater than 0, then repeatedly transform the element with the smallest value to consume K
        int result = 0;
        for (int a : A) result += a;        // get sum
        return result;
    }
};

2. Gas Station

LeetCode Link: 134. Gas Station
There are n gas stations along a circular route, where the amount of gas at the ith station is gas[i].

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from the ith station to its next (i + 1)th station. You begin the journey with an empty tank at one of the gas stations.

Given two integer arrays gas and cost, return the starting gas station’s index if you can travel around the circuit once in the clockwise direction, otherwise return -1. If there exists a solution, it is guaranteed to be unique

Example 1:

Input: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
Output: 3
Explanation:
Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 4. Your tank = 4 - 1 + 5 = 8
Travel to station 0. Your tank = 8 - 2 + 1 = 7
Travel to station 1. Your tank = 7 - 3 + 2 = 6
Travel to station 2. Your tank = 6 - 4 + 3 = 5
Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3.
Therefore, return 3 as the starting index.
Example 2:

Input: gas = [2,3,4], cost = [3,4,3]
Output: -1
Explanation:
You can’t start at station 0 or 1, as there is not enough gas to travel to the next station.
Let’s start at station 2 and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 0. Your tank = 4 - 3 + 2 = 3
Travel to station 1. Your tank = 3 - 3 + 3 = 3
You cannot travel back to station 2, as it requires 4 unit of gas but you only have 3.
Therefore, you can’t travel around the circuit once no matter where you start.

Constraints:

n == gas.length == cost.length
1 <= n <= 105
0 <= gas[i], cost[i] <= 104

Analysis and Solution

Violent Solution

LeetCode C++ as followings Violent Solution

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        for (int i = 0; i < cost.size(); i++) {
            int rest = gas[i] - cost[i]; // record remaining gas
            int index = (i + 1) % cost.size();
            while (rest > 0 && index != i) { // Simulate driving around starting from i (if rest==0, then the answer is not unique)
                rest += gas[index] - cost[index];//get remaining gas
                index = (index + 1) % cost.size();
            }
            // If you run around with i as the starting point, and the remaining gas is >=0, return to the starting position
            if (rest >= 0 && index == i) return i;
        }
        return -1;
    }
};

Greedy Algorithm

LeetCode C++ as followings Greedy Algorithm

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int curSum = 0;//to record sum of remaining gas
        int totalSum = 0;//to record sum of accumulated rest[i]=gas[i]-cost[i]
        int start = 0;
        for (int i = 0; i < gas.size(); i++) {
            curSum += gas[i] - cost[i];
            totalSum += gas[i] - cost[i];
            if (curSum < 0) {   // Once the current accumulated rest[i] and curSum are less than 0
                start = i + 1;  // The starting position is updated to i+1
                curSum = 0;     // curSum starts from 0
            }
        }
        if (totalSum < 0) return -1; // indicates that cannot make it done
        return start;
    }
};

3. Candy

LeetCode Link: 135. Candy
There are n children standing in a line. Each child is assigned a rating value given in the integer array ratings.

You are giving candies to these children subjected to the following requirements:

Each child must have at least one candy.
Children with a higher rating get more candies than their neighbors.
Return the minimum number of candies you need to have to distribute the candies to the children.

Example 1:

Input: ratings = [1,0,2]
Output: 5
Explanation: You can allocate to the first, second and third child with 2, 1, 2 candies respectively.
Example 2:

Input: ratings = [1,2,2]
Output: 4
Explanation: You can allocate to the first, second and third child with 1, 2, 1 candies respectively.
The third child gets 1 candy because it satisfies the above two conditions.

Constraints:

n == ratings.length
1 <= n <= 2 * 104
0 <= ratings[i] <= 2 * 104

Analysis and Solution

Greedy Algorithm

LeetCode C++ as followings Greedy Algorithm

class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> candyVec(ratings.size(), 1);
        // from front to back
        for (int i = 1; i < ratings.size(); i++) {
            if (ratings[i] > ratings[i - 1]) candyVec[i] = candyVec[i - 1] + 1;//If ratings[i] > ratings[i - 1] then [i] must have one more candy than [i - 1], so greedy Algorithm: candyVec[i] = candyVec[i - 1] + 1
        }
        // from back to front
        for (int i = ratings.size() - 2; i >= 0; i--) {//If ratings[i] > ratings[i + 1], at this time candyVec[i] (the number of candies for the i-th child) has two options, one is candyVec[i + 1] + 1 (from the one on the right) The number of candies obtained by 1), one is candyVec[i] (the number of candies obtained by the right child is greater than that of the left child).
            if (ratings[i] > ratings[i + 1] ) {
                candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1);//Take candyVec[i + 1] + 1 and candyVec[i] with the largest number of candies. CandyVec[i] only takes the largest candy to keep more candies on the left candyVec[i - 1] than the right candyVec[i + 1] ] of candy.
            }
        }
        // get result
        int result = 0;
        for (int i = 0; i < candyVec.size(); i++) result += candyVec[i];
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值