LeetCode 第33天 | 1005. K 次取反后最大化的数组和 135. 分发糖果 134. 加油站

1005. K 次取反后最大化的数组和
按照绝对值大小降序排序,然后将负值变正,如果所有负值都正了,但是还有k余量且为奇数,那就将绝对值最小值(最后一个元素)取反,否则直接结束。

class Solution {
public:
// 类内调用函数指针静态(猜的)
    static bool cmp(int a, int b){
        return abs(a)>abs(b);
    }
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        // 按照绝对值从大到小排序
        sort(nums.begin(), nums.end(), cmp);
        for (int i = 0; i<nums.size(); i++) {
            if (k>0 && nums[i]<0){
                nums[i] *= -1;
                k--; 
            }
        }
        int res = 0;
        if (k%2 == 1){
            nums[nums.size()-1] *= -1;
        }
        for (auto i:nums){
            res += i;
        }
        return res;
    }
};

135. 分发糖果

从左往右,找右边比左边大的,给右边赋值为左边加一。从右往左,找左边比右边大的,给左边赋值 右边加一与 左边本身 的较大值(兼顾左边)。

class Solution {
public:
    int candy(vector<int>& ratings) {
        int res = 0;
        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);
            }
        }
        for (auto i : candyVec){
            res += i;
        }
        return res;
    }
};

134. 加油站

用数组前缀和,从零开始找出发点,如果当前前缀和小于零,那么前面的都不能作为出发点,直接从后一个再出发。最后如果总和小于零就无法找到结果,返回-1。

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int totalSum = 0;
        int curSum = 0;
        int start = 0;
        for (int i = 0; i<gas.size(); i++) {
            totalSum += (gas[i] - cost[i]);
            curSum += (gas[i] - cost[i]);
            if (curSum < 0) {
                start = i+1;
                curSum = 0;
            }
        }
        if (totalSum < 0) return -1;
        return start;
    }
};

你可能感兴趣的:(leetcode,算法,职场和发展)