算法学习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();
}
相关推荐
lxl13075 小时前
学习C++(5)运算符重载+赋值运算符重载
学习
只是懒得想了5 小时前
C++实现密码破解工具:从MD5暴力破解到现代哈希安全实践
c++·算法·安全·哈希算法
m0_736919106 小时前
模板编译期图算法
开发语言·c++·算法
dyyx1116 小时前
基于C++的操作系统开发
开发语言·c++·算法
AutumnorLiuu6 小时前
C++并发编程学习(一)——线程基础
开发语言·c++·学习
m0_736919106 小时前
C++安全编程指南
开发语言·c++·算法
CS创新实验室6 小时前
关于 Moltbot 的学习总结笔记
笔记·学习·clawdbot·molbot
蜡笔小马6 小时前
11.空间索引的艺术:Boost.Geometry R树实战解析
算法·r-tree
-Try hard-6 小时前
数据结构:链表常见的操作方法!!
数据结构·算法·链表·vim
2301_790300966 小时前
C++符号混淆技术
开发语言·c++·算法