代码随想录算法训练营day29

6 阅读2分钟

1005 k次取反后最大化的数组和 1.对数据进行绝对值排序,优先取反绝对值最大的负数 2.如果k还没有用完,反复取反绝对值最小值,将k用尽

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

134.加油站 1.必须设置两个累积油量做判断,一个时rest的所有油量和,一个时不断重置的当前油量和


class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
    // 1. 初始化rest向量,指定大小为gas.size(),避免下标越界
        vector<int> rest(gas.size()); 
        int total_sum = 0; // 所有站点的总剩余油量(判断是否存在解)
        int cur_sum = 0;   // 当前起始点开始的累积剩余油量
        int start = 0;     // 候选起始点

        for (int i = 0; i < gas.size(); i++) {
            // 2. 给rest向量赋值(此时rest已有对应空间,无越界)
            rest[i] = gas[i] - cost[i]; 
            total_sum += rest[i]; // 累计总剩余油量
            cur_sum += rest[i];   // 累计当前起始点的剩余油量

            // 3. 若当前累积油量<0,说明从start到i无法走完,更新起始点并重置cur_sum
            if (cur_sum < 0) {
                start = i + 1;    // 新起始点为i+1
                cur_sum = 0;      // 关键:重置当前累积油量,重新计算
            }
        }

        // 总剩余油量<0 → 整体油量不足,无解;否则返回候选起始点
        return total_sum < 0 ? -1 : start;
    }
};

135分发糖果 1.采用两次贪心算法


class Solution {
public:
    int candy(vector<int>& ratings) {
        int n = ratings.size();
        if (n == 0) return 0; // 边界处理:空数组直接返回0
        //采用贪心算法,对左右两边顺序,都使用一次贪心算法
        vector<int> candycost(ratings.size());//初始化每个孩子需要分配的糖果向量
        //先每个孩子都分发一个糖果
        for(int i=0;i<ratings.size();i++){
            candycost[i]=1;
        }
        //先从左至右按照评分分发糖果
        for(int i=1;i<ratings.size();i++){//
            if (ratings[i] > ratings[i - 1]) candycost[i] = candycost[i - 1] + 1;
        }
        //从右至左按照评分分发糖果
        for(int i=ratings.size()-2;i>=0;i--){
            if(ratings[i]>ratings[i+1])   candycost[i] = max(candycost[i], candycost[i+1] + 1);
        }
        int sum=0;
        for(int i:candycost){
            sum+=i;
        }
        return sum;
    }
};

860 柠檬水找零


class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        //直接使用三个数字做累计记录找零就行
        int five=0;
        int ten=0;
        int twenty=0;
        for(int i=0;i<bills.size();i++){
            if(bills[i]==5)
              five++;
            else if(bills[i]==10){
                if(five<=0) return false;
                else{
                    five--;
                    ten++;
                }
            }
            else if(bills[i]==20){
                if(ten>0&&five>=1){
                    ten--;
                    five--;
                }
                else if(ten==0&& five>=3){
                    five=five-3;
                }
                else
                return false;
            }
        }
        return true;
    }
};