代码随想录算法训练营第二十八天 | 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II 1005.K次取反后最大化的数组和

122.买卖股票的最佳时机II  

       因为可以在同一点购买出售,所以只要保证第二天卖出有利润,都可以买入,反映到数组上条件为nums[i] < nums[i+1],然后把所有利润累加。

class Solution {
public:
    int maxProfit(vector<int>& nums) {
        int sum = 0;
        for(int i = 0; i < nums.size() - 1; ++i) {
            if(nums[i] < nums[i+1]) {
                sum += nums[i+1] - nums[i];
            } 
        }
        return sum;
    }
};

55. 跳跃游戏

        判断跨越区间是否能覆盖最后一个元素,如果能就返回true,不能就返回false;

        但是疏忽了一点,当有元素为0时,不能保证一定能跳到后面的元素。比如说[3,2,1,0,4],无论怎么跳都只能到0这个点,所以遍历范围是不合理的。

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int cover = 0;
        for(int i = 0; i < nums.size(); ++i) {
            cover = nums[i] + i;
            if(cover > nums.size() - 1) return true;
        }   
        return false;     
    }
};

        修改后: 只能跳跃到cover范围内的所有元素,所以范围修改成cover;其次使用max函数保证cover是能达到的最远路径。

class Solution {
public:
    bool canJump(vector<int>& nums) {
        if(nums.size() == 1) return true;
        int cover = nums[0];
        for(int i = 0; i <= cover; ++i) {
            cover = max(cover, nums[i] + i);
            if(cover >= nums.size() - 1) return true;
        }   
        return false;     
    }
};

45.跳跃游戏II

        思路是一次跳跃中尽可能大地覆盖元素,然后从已覆盖的元素中判断下一次能不能到达最后一个元素;不能则循环,能则结束。代码中:

        cover指从元素所覆盖的长度(和第一个元素的距离)

        curCover指当前的元素出发所能到达的最远长度

        maxCover指在当前元素到达最远长度前,从某一元素出发能到达的下个最远长度

        代码整体逻辑则是先走一步到达curCover前,期间寻找到maxCover;下一步再按照maxCover走。

class Solution {
public:
    int jump(vector<int>& nums) {
        if(nums.size() == 1) return 0;
        int cover = nums[0];
        int maxCover = cover;
        int sum = 0;
        int curCover;
        while(1) {
            curCover = maxCover;
            if(curCover >= nums.size() - 1) {
                sum++;
                return sum;
            }
            sum++;
            for(int i = 0; i <= curCover; ++i) {
                cover = nums[i] + i;
                if(maxCover >= cover) continue;
                else{
                    //记录这次范围内能到达的最远值
                    maxCover = cover;  
                }                    
            }
        }        
        return sum;
    }
};

1005.K次取反后最大化的数组和

        首先得排序,对于正负元素混合的数组首先对最小的负数取反;其次。对于全正数的数组,则k为偶数可以取回原数,k为奇数则取最小的数字为负。

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end());
        int sum = 0;
        for(auto& n:nums) {
            if(k <= 0 || n >= 0) break;
            if(n < 0) {
                n = -n;
                k--;
            }
        }    
        sort(nums.begin(), nums.end());
        //接着没负数了
        for(auto& n:nums) {
            if(k != 0 && k % 2) n = -n;
            break;
        }
        //求和
        for(auto n : nums) {
            cout << n<< endl;
            sum += n;
        }    
        return sum;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值