[Leetcode 60 days with brushing] day33 backtracking algorithm - 1005. K times of negation and maximized array sum 134. Gas station 135. Distributing candy


  topic:

1005. Array Sum Maximized After K Inversions

Given an array of integers  nums and an integer  k , modify the array as follows:

  • Select a subscript  i and  nums[i] replace with  -nums[i] .

Repeat this process exactly  k times. The same subscript can be selected multiple times  i .

After modifying an array in this way, return  the largest sum possible for the array  .

Example 1:

Input: nums = [4,2,3], k = 1
 Output: 5
 Explanation: Select subscript 1, nums becomes [4,-2,3].

Example 2:

Input: nums = [3,-1,0,2], k = 3
 Output: 6
 Explanation: Select the subscript (1, 2, 2), and nums becomes [3,1,0,2].

Example 3:

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

hint:

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

Thinking process and knowledge points: 

The idea of ​​this question is actually easier to think about, how can the array sum be the largest?

Greedy idea, local optimum: let the negative number with large absolute value become a positive number, the current value reaches the maximum, and the overall optimum: the sum of the entire array reaches the maximum.

Local optimum can lead to global optimum.

Then if all the negative numbers are turned into positive numbers, K is still greater than 0. The problem at this time is how to change the positive and negative numbers K times to maximize the array sum.

Then it is another greedy: local optimum: only find the positive integer with the smallest value to reverse, and the current value can reach the maximum (for example, an array of positive integers {5, 3, 1}, reverse 1 to get -1 than reverse 5 Most of the obtained -5), the global optimum: the entire array and reach the maximum.


 answer:

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);       // 第一步
        for (int i = 0; i < A.size(); i++) { // 第二步
            if (A[i] < 0 && K > 0) {
                A[i] *= -1;
                K--;
            }
        }
        if (K % 2 == 1) A[A.size() - 1] *= -1; // 第三步
        int result = 0;
        for (int a : A) result += a;        // 第四步
        return result;
    }
};

  topic:

134. Gas station

There is a gas station on a ring road  n , and the first  i gas station has gasoline  gas[i] liters.

You have a car with unlimited fuel tank capacity, and it takes gasoline  liters to drive from the first gas station to the first gas station . You start off from one of the gas stations, starting with an empty tank. i  i+1 cost[i] 

Given two integer arrays  gas and  cost , if you can drive around the loop in sequence, return the number of the gas station at the time of departure, otherwise return  -1 . If a solution exists,   it is  guaranteed to be unique  .

Example 1:

Input: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
 Output: 3
 Explanation:
 Starting from gas station No. 3 (at index 3), you can get 4 liters of petrol. At this point the fuel tank has = 0 + 4 = 4 liters of petrol
Drive to gas station No. 4, at this time the tank has 4 - 1 + 5 = 8 liters of gasoline
Drive to Gas Station No. 0, at this time the fuel tank has 8 - 2 + 1 = 7 liters of gasoline
Go to Gas Station No. 1, now the tank has 7 - 3 + 2 = 6 liters of petrol
Drive to gas station 2, now the tank has 6 - 4 + 3 = 5 liters of gasoline
Driving to gas station 3, you need to consume 5 liters of gasoline, just enough to get you back to gas station 3.
Therefore, 3 can be the starting index.

Example 2:

Input: gas = [2,3,4], cost = [3,4,3]
 Output: -1
 Explanation:
 You cannot start from gas station 0 or 1, because there is not enough gas for you to travel to the next a gas station.
We start from gas station 2 and get 4 liters of petrol. At this point the fuel tank has = 0 + 4 = 4 liters of petrol
Drive to gas station 0, now the tank has 4 - 3 + 2 = 3 liters of gasoline
Go to gas station 1, now the tank has 3 - 3 + 3 = 3 liters of petrol
You can't go back to gas station 2, because the return trip takes 4 liters of gas, but your tank only has 3 liters of gas.
So, no matter what, you can't drive around the loop.

hint:

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

Thinking process and knowledge points: 

Greedy selection directly from the global, the situation is as follows:

  • Situation 1: If the sum of gas is less than the sum of cost, no matter where you start from, you must not be able to run around

  • Situation 2: rest[i] = gas[i]-cost[i] is the oil left in one day, i starts to calculate and accumulate from 0 to the last station, if the accumulation does not show a negative number, it means that starting from 0, the oil has not been cut off However, then 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.


 answer:

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;  // 情况1
        if (min >= 0) return 0;     // 情况2
                                    // 情况3
        for (int i = gas.size() - 1; i >= 0; i--) {
            int rest = gas[i] - cost[i];
            min += rest;
            if (min >= 0) {
                return i;
            }
        }
        return -1;
    }
};

  topic:

135. Handing out candy

n children stand in a row. You are given an array of integers  ratings representing each child's rating.

You need to distribute candy to these children according to the following requirements:

  • Each child is assigned at least  1 one candy.
  • The child with the higher score of two adjacent children gets more candies.

Please distribute candies to each child, calculate and return  the minimum number of candies that need to be prepared  .

Example 1:

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

Example 2:

Input: ratings = [1,2,2]
 Output: 4
 Explanation: You can distribute 1, 2, and 1 candy to the first, second, and third children, respectively.
     The third child only gets 1 candy, which satisfies the two conditions in the title.

hint:

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

Thinking process and knowledge points: 

This question must be determined after one side is determined, and then the other side is determined. For example, compare the left side of each child, and then compare the right side. If you consider both sides together, you will lose sight of the other .

First determine the situation where the right score is greater than the left (that is, traverse from front to back)

At this time, the local optimum: as long as the score on the right is higher than that on the left, the child on the right will have one more candy. The global optimum: among the adjacent children, the right child with a higher score will get more candy than the left child

Local optimum can lead to global optimum.

If ratings[i] > ratings[i - 1] then [i] must have one more sugar than [i - 1], so greedy: candyVec[i] = candyVec[i - 1] + 1


 answer:

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;
    }
};

Welcome to like, bookmark, comment, your encouragement is the biggest motivation for my creation! (๑╹◡╹)ノ"""

Copyright statement: This article is an original article of CSDN blogger "Dumengjiu", which follows the CC 4.0 BY-SA copyright agreement. For reprinting, please attach the original source link and this statement.
Original link: Dumengjiu's blog_CSDN blog-csdn domain blogger

Guess you like

Origin blog.csdn.net/weixin_53310927/article/details/131376113