算法学习day28-贪心算法

买卖股票2

核心思路

  • 贪心算法

    • 如果想到其实最终利润是可以分解的,那么本题就很容易了!

      如何分解呢?

      假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。

      相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。

      此时就是把利润分解为每天为单位的维度,而不是从 0 天到第 3 天整体去考虑!

    • 要求最大利润, 那就拆分成每天都能获得正利润. 这样汇总之后就是最大利润了

    题解

    • 自己写的

      java 复制代码
      public int maxProfit(int[] prices) {
          int maxProfit = 0;
          int preProfit = 0;
          int prePrice = prices[0];
          for (int i = 1; i < prices.length; i++) {
              if (prices[i] < prePrice) {
                  maxProfit += preProfit;
                  preProfit = 0;
              } else {
                  preProfit = preProfit + prices[i] - prePrice;
              }
              prePrice = prices[i];
          }
          return maxProfit + preProfit;
      }
    • 优化

      java 复制代码
      public int maxProfit(int[] prices) {
          int result = 0;
          for (int i = 1; i < prices.length; i++) {
              //只收集 每天卖出是正利润的. 全局下就是最大利润
              result += Math.max(prices[i] - prices[i - 1], 0);
          }
          return result;
      }

跳跃游戏

核心思路

  • 要求最终能不能跳跃到最后位置, 只需要找到每个元素可跳跃的最大范围, 这样到最后, 每个元素的最大范围都求出来了, 那么全局的可跳跃的最大范围也就求出来了

    java 复制代码
    public boolean canJump(int[] nums) {
        if (nums.length <= 1) return true;
        int max = nums[0];
        for (int i = 1; i <= max; i++) {
            max = Math.max(max, i + nums[i]);
            if (max >= nums.length - 1) {
                return true;
            }
        }
        return false;
    }

跳跃游戏2

核心思路

  • 核心依然是求每个元素的最大跳跃范围.

  • 只是 在该元素的跳跃范围内, 要找到 其中的可跳跃范围最大的某个元素. 直到执行到范围末尾, count++. 并更新最大跳跃范围

    java 复制代码
    public int jump(int[] nums) {
        if (nums.length <= 1) return 0;
        int count = 0;
        //当前的最大范围
        int curDistance = 0;
        //当前范围内的, 元素的可跳跃的最大范围
        int maxDistance = 0;
        for (int i = 0; i < nums.length; i++) {
            maxDistance = Math.max(maxDistance, i + nums[i]);
            if (maxDistance >= nums.length - 1) {
                return ++count;
            }
            if (i == curDistance) {
                count++;
                curDistance = maxDistance;
            }
        }
        return count;
    }

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

核心思路

  • 这道题要怎么贪心呢, 正数越多值就越大, 那就是尽可能的将负数转正
  • 如果负数全部转正之后, k还没用完呢?
    • 那就是第二个贪心, 只对值最小的一个数进行取反, 这样得到的和就是最大的

题解

java 复制代码
public static int largestSumAfterKNegations(int[] nums, int k) {
    Arrays.sort(nums);
    for (int i = 0; i < nums.length; i++) {
        if(nums[i] < 0 && k>0){
            k--;
            nums[i] = -nums[i];
        }
    }
    Arrays.sort(nums);
    if(k % 2 == 1) nums[0] = -nums[0];
    return IntStream.of(nums).sum();
}
  • 将数组根据绝对值大小进行排序, 这样就不用第二次排序了
java 复制代码
public static int largestSumAfterKNegations(int[] nums, int k) {
    nums = IntStream.of(nums).boxed().sorted((a, b) -> Math.abs(b) - Math.abs(a)).mapToInt(Integer::valueOf).toArray();
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] < 0 && k > 0) {
            k--;
            nums[i] = -nums[i];
        }
    }
    if (k % 2 == 1) nums[nums.length - 1] = -nums[nums.length - 1];
    return IntStream.of(nums).sum();
}
相关推荐
aini_lovee20 小时前
MATLAB圆锥滚子轴承滚子参数分析程序
人工智能·算法·matlab
_olone20 小时前
牛客每日一题:显生之宙(Java)
java·开发语言·算法·牛客
嫂子开门我是_我哥20 小时前
心电域泛化研究从0入门系列 | 第二篇:心电信号预处理全攻略——扫清域泛化建模的第一道障碍
人工智能·算法·ecg
小光学长20 小时前
基于ssm的膳食健康管理系统e6whl4q7(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·开发语言·数据库·学习·ssm
wefg121 小时前
【算法】算数基本定理、分解质因数
算法
j_xxx404_21 小时前
力扣困难算法精解:串联所有单词的子串与最小覆盖子串
java·开发语言·c++·算法·leetcode·哈希算法
挠头猴子21 小时前
一个数组去重,两个数组找不同或相同
数据结构·算法
big_rabbit050221 小时前
[算法][力扣167]Two Sum II
算法·leetcode·职场和发展
颜酱21 小时前
二分图核心原理与判定算法
javascript·后端·算法
weixin_4588726121 小时前
东华复试OJ二刷复盘7
学习