352、 买卖股票的good时机和最大子数组(todo,动态规划)

一、题目

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

示例 1:

输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
示例 2:

输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

来源:力扣(LeetCode)
链接:力扣
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、暴力解法,不让提交

/**

   * @param args

   */

  public static void main(String[] args) {

      int maxProfit = maxProfit(new int[] {715369});

      System.out.println(maxProfit);

  }

  /**

   * 2重for循环, 超出时间限制

   *

   * @param prices

   * @return

   */

  public static int maxProfit(int[] prices) {

      int max = 0;

      for (int i = 0; i < prices.length - 1; i++) {

          for (int j = i + 1; j < prices.length; j++) {

              if (prices[j] - prices[i] > max) {

                  max = prices[j] - prices[i];

              }

          }

      }

      return max;

  }

三、一点思考,发现了规律

7,1,5,3,6,9;相邻2个数的差:-6 4 -2 3 3

1,3,5,3,7,6,2; 相邻2个数的差:2,2,-2,3,4,-1,-4

题目转换为,连续x(x可以在1到N-1个数)之和。想不到 怎么解,思路可能比较复杂?

这个思路,可能不对;

但是,我分析:这种类型的题目,很容易看出有一定的规律。

比较好的解法是:找到对应的解法。这种数字类的题目,很容易知道是 数学里面的概念。

然而,我数学太渣,大学的数学课,不喜欢读额。

public class BestTimeToBuyAndSellStock {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // 暴力破解
        final int[] prices = new int[] {7, 1, 5, 3, 6, 9,12};
        int maxProfit = maxProfit(prices);
        System.out.println(maxProfit);
        // 先转换问题 为 求最大子序和
        int[] pricesSub = new int[prices.length - 1];
        for (int i = 0; i < prices.length - 1; i++) {
            pricesSub[i] = prices[i + 1] - prices[i];
        }
        int maxProfit2 = maxSubArray(pricesSub);
        System.out.println(maxProfit2);

    }

    /**
     * 雷:这个方法的关键点 核心理解;如果 sum > 0,则说明 sum 对结果有增益效果,则 sum 保留并加上当前遍历数字 <br/>
     * 如果 sum <= 0,则说明 sum 对结果无增益效果,需要舍弃,则 sum 直接更新为当前遍历数字 <br/>
     * 抽象了3个变量值:当前遍历num、当前求和、当前求和sum和num比较、sum和当前最大sum比较
     * 
     * @param nums
     * @return
     */
    // 作者:guanpengchn
    // 链接:https://leetcode-cn.com/problems/maximum-subarray/solution/hua-jie-suan-fa-53-zui-da-zi-xu-he-by-guanpengchn/
    // 来源:力扣(LeetCode)
    // 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    public static int maxSubArray(int[] nums) {
        int ans = nums[0];
        int sum = 0;
        for (int num : nums) {
            if (sum > 0) {
                sum += num;
            } else {
                sum = num;
            }
            ans = Math.max(ans, sum);
        }
        return ans;
    }

    /**
     * 2重for循环, 超出时间限制
     * 
     * @param prices
     * @return
     */
    public static int maxProfit(int[] prices) {
        int max = 0;
        for (int i = 0; i < prices.length - 1; i++) {
            for (int j = i + 1; j < prices.length; j++) {
                if (prices[j] - prices[i] > max) {
                    max = prices[j] - prices[i];
                }
            }
        }
        return max;
    }
}

四、官方解法:有问题

先找到历史最低点,再求后面的最高点。

五、网上标准解决:动态规划

我连动态规划的概念,都没搞清楚。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值