文章链接: 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II 1005.K次取反后最大化的数组和

视频链接: 122.买卖股票的最佳时机 II 55. 跳跃游戏 45.跳跃游戏 II 1005.K次取反后最大化的数组和

题目链接: 122.买卖股票的最佳时机 II 55. 跳跃游戏 45.跳跃游戏 II 1005.K次取反后最大化的数组和


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

思路:

将买和卖两天的收益转换成每天的收益。举例如下:

prices[3] =  prices[3] - prices[2] + prices[2] - prices[1]

根据以上的结论,我们可以将是差值是 正数 的 全部相加 ,从而得到最大总利润。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int result = 0;
        for(int i = 1; i < prices.size(); i++) {
            result += max(prices[i] - prices[i - 1], 0); // 找正数
        }
        return result;
    }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.


55.跳跃游戏

思路:

局部最优:选距离最远的跳。


注意:

是最大长度,不是固定长度。

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int result = 0;
        int maxNum = 0; // 表示能跳到得到最远数组下标
        for(int i = 0; i <= maxNum; i++) {
        // i <= maxNum;表示只有能跳到的数组下标,才有资格遍历到、
        
            if(maxNum >= nums.size() - 1) return true;
            maxNum = max(maxNum, i + nums[i]); // 局部最优
        }
        return false;
    }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.


45.跳跃游戏II

思路:

局部最优:用 最少的步数 尽可能的增大覆盖范围

class Solution {
public:
    int jump(vector<int>& nums) {
        if(nums.size() == 1) return 0;
        int result = 0;
        int curMaxDistance = 0;
        int nextMaxDistance = 0;
        for(int i = 0; i < nums.size(); i++) {
            nextMaxDistance = max(nextMaxDistance, i + nums[i]); // 更新下一步最远覆盖范围
            if(i == curMaxDistance) { // 遇到当前覆盖最远的距离得到下标
                result++; // 走下一步
                curMaxDistance = nextMaxDistance;
                if(nextMaxDistance >= nums.size() - 1) {
                    break;
                }
            }
        }
        return result;
    }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.


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

思路:

第一步贪心:将负数都转换为正数

第二步贪心:将剩下的转换次数全都用在最小的正数上

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        // 第一步贪心:将负数都转换为正数
        sort(nums.begin(), nums.end());
        for(int i = 0; i < nums.size(); i++) {
            if(nums[i] <= 0 && k > 0) {
                nums[i] = (-1) * nums[i];
                k--;
            }
        }

        // 第二步贪心:将剩下的转换次数全都用在最小的正数上
        sort(nums.begin(), nums.end()); 
        if(k % 2 == 1) {
            nums[0] = (-1) * nums[0];
        }
        int result = 0;
        for(int num : nums) {
            result += num;
        }
        return result;
    }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.