算法训练营36

题目1:

根据通过情况反复挑战最终AC过了,这里和原来的差别是他的排序是用绝对值排序的,这样的思路会很简单

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end());
        int i;
        for(i = 0;i < nums.size();i++) {
            // 这里就是排完序之后如果是负数就给他变成整的
            if(nums[i] < 0) {
                nums[i] = -nums[i];
                k--;
            }else if(nums[i] == 0) {
                // 如果遇到0 其实省的K次反转直接用到0这里就行
                break;
            }else {
                // 反转完负的没有遇到0 这里就要根据剩余的K判断了
                // 如果K能整除2 那就正的还是正的,否则就要判断原来数组里最小的正数
                // 和负数取反后的正数谁小,谁小就对其去负数
                if(k % 2 != 0) {
                    if(i > 0 && nums[i] > nums[i - 1]) nums[i - 1] = - nums[i - 1];
                    else nums[i] = - nums[i];
                }
                break;
            }
            // 这里是k < 数组个数的情况直接, k次数完了就break
            if(k == 0) break;
        }
        // 如果K 大于 数组个数  就是根据剩余K 来判断是否对最小的正数反转
        if(k != 0 && i == nums.size()) {
            sort(nums.begin(), nums.end());
            if(k % 2 != 0) nums[0]  = -nums[0];
        }
        int sum = 0;
        for(int j =0;j < nums.size();j++)  {
            sum += nums[j];
        }
        return sum;
    }
};

这里要注意要先变绝对值大的负数 

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(nums[i] < 0 && k > 0) {
                nums[i] = -nums[i];
                k--;
            }
        }
        if(k % 2 != 0) nums[nums.size()  - 1] = -nums[nums.size() - 1];
        int sum = 0;
        for(int i = 0;i < nums.size();i++) {
            sum += nums[i];
        }
        return sum;
    }
};

题目2:134. 加油站 - 力扣(LeetCode)

代码随想录上的思路,让加油 - 耗油,如果所有的总和都<0 那肯定跑不完,然后用一个currsum 统计从 0 开始到当前i 的 剩余油之和,如果 < 0 说明 起始位置肯定在为 i + 1,然后currsum 置零,在重复上面操作,最后返回 start 就行。

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

题目3:135. 分发糖果 - 力扣(LeetCode)

这道题从两边开始算就好,先从左向右只考虑右边小孩比左边小孩大,然后从右向左考虑,最后取两次糖果数组里大的,然后最后求和即可

class Solution {
public:
    int candy(vector<int>& ratings) {
        if(ratings.size() == 1) return 1;
        vector<int> leftcandy(ratings.size(), 1);
        vector<int> rightcandy(ratings.size(), 1);
        for(int i = 1;i < ratings.size();i++) {
            if(ratings[i] > ratings[i - 1]) {
                leftcandy[i] = leftcandy[i - 1] + 1;
            }
        }
        for(int i = ratings.size() - 2;i >= 0;i--) {
            if(ratings[i] > ratings[i + 1]) {
                rightcandy[i] = rightcandy[i + 1] + 1;
            }
        }
        int sum = 0;
        for(int i = 0;i < rightcandy.size();i++) {
            rightcandy[i] = max(leftcandy[i], rightcandy[i]);
            sum += rightcandy[i];
        }
        return sum;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值