文章目录

  • 一、题目
    • 1. 题目描述
    • 2. 示例
    • 3. 题目分析
  • 二、解法
    • 1. 个人解法(未解出)
      • (1)做题反思
    • 2. 官网高星解法
      • (1)暴力搜素(有递归,未完全看懂)
      • (2)贪心算法
      • (3)动态规划

一、题目

1. 题目描述

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

2. 示例

示例 1:
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
示例 2:
输入: [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例 3:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

3. 题目分析

本题的目的是让买卖股票的利润最大化,题中说明可以尽可能多的完成交易,但是不能同时参与多笔交易,也就是说想买一只股票的时候,手里是不能有其他股票的,并且一天内按照当天价格卖出买入多次也是可以的(没有手续费的任性)。

二、解法

1. 个人解法(未解出)

(1)做题反思

对题目理解不到位
在读题的时候已经理解错误,以为在一天内只能买或者卖,执行一次操作。
算法基础薄弱
虽然对题目的理解出现偏差,但是按照这个思路用穷举法依旧可以得到结果,但是没有编出相应代码。

2. 官网高星解法

(1)暴力搜素(有递归,未完全看懂)

代码:

 public int maxProfit(int[] prices) {return calculate(prices, 0);}public int calculate(int prices[], int s) {//递归终止条件--表示数组已经遍历完毕,返回0if (s >= prices.length)return 0;int max = 0;//start=第s天~最后一天for (int start = s; start < prices.length; start++) {int maxprofit = 0;//i=start+1~最后一天for (int i = start + 1; i < prices.length; i++) {//有收益的话if (prices[start] < prices[i]) {//收益为这段时间的收益+数组剩余时间段的收益int profit = calculate(prices, i + 1) + prices[i] - prices[start];//maxprofit为此趟遍历最大收益if (profit > maxprofit)maxprofit = profit;}}//max为所有遍历中的最大收益if (maxprofit > max)max = maxprofit;}return max;}

解法分析:
利用递归,计算所有可能的交易组合对应利润,找出最大利润组合。
非常耗费时间和空间:
时间复杂度:O(nn)O(n^n)O(nn),调用递归次数为:nnn^nnn
空间复杂度:O(n)O(n)O(n),递归的深度为:nnn
提交截图:

(2)贪心算法

贪心算法简述
对问题求解时,分步决策的,每一步总是做出当前看来最好的选择。即,不从整体最优加以考虑,做出的是局部最优解。
解法分析
这道题“贪心”的地方在于将一个周期的最优解分解到每两天之间,对于 “今天的股价 - 昨天的股价”,得到的结果有 3 种可能:(1)正数(2)0(3)负数,我们贪心决策只累计正数,累计就相当于执行“昨日买入,今日卖出”。
代码

public class Arraygupiao2 {int maxProfit(int[] prices) {int max = 0;for (int i = 0; i < prices.length - 1; i++) {if (prices[i + 1] - prices[i] > 0) {//                进行操作i天买入,第二天卖出max += prices[i + 1] - prices[i];}}return max;}public static void main(String[] args) {int[] prices = {7, 1, 5, 3, 6, 4};Arraygupiao2 arr = new Arraygupiao2();int profit = arr.maxProfit(prices);System.out.println(profit);}
}

算法分析
时间复杂度:O(n)O(n)O(n)
空间复杂度:O(1)O(1)O(1)
提交截图

(3)动态规划

动态规划算法简述
动态规划是一种分阶段求解决策略的数学思想,在每一个阶段,都需要做出决策,让整个过程达到最好状态。每个决策都依赖于上一个决策的结果(目前的状态),又会影响以后的决策。

解法分析

  • 定义状态矩阵dp[i][j]

i表示到索引为i的那一天能获得的最大利益
j表示索引为i的那一天是持有股票,还是卖出股票持有现金。这里0表示持有现金,1表示持有股票。
dp[i][0]表示当天卖出的最大利益,dp[i][1]表示当天买入持有的最大利益
note:最大利益也就是指手里的盈利现金

  • 找状态转移方程

状态从持有现金开始,到最后一天,我们的状态应该是持有现金;
每一天的状态可以转移,也可以不变。如果状态发生转移,转移后的利益应该是转移前的利益+转移过程产生的利益(买入为负数,卖出为正数)

  • 确定开始状态

当天如果不买入股票:最大利益为0 dp[0][0] = 0
当天如果买入股票:此时应该手里利益为负数 dp[0][1] = -prices[i]

  • 确定中间状态

中间每天状态可以发生转移,也可以不转移。
第i天卖出的最大利益=第i-1天卖出的最大利益(状态保持不动)or 第i-1天买入的最大利益+第i天股价(状态发生转移)

 dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);

第i天买入的最大利益=第i-1天买入的最大利益(状态保持不变)or 第i-1天卖出的最大利益-第i天股票价格(状态发生转移)

  dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);
  • 确定终止状态

最后一天手里应该持有现金,也就是应该输出dp[len - 1][0]
代码

public class Arraygupiao2_2 {int max(int temp1, int temp2) {if (temp1 > temp2)return temp1;return temp2;}int maxProfit(int[] prices) {int le = prices.length;int[][] dp = new int[le][2];dp[0][0] = 0;dp[0][1] = 0 - prices[0];for (int i = 1; i < le; i++) {//第i天是卖出状态,则:可能是第i-1是卖出状态,保持至今天;可能是第i-1天是买入状态,第i天卖出(当前收益为:第i-1天买入状态的收益+第i天的收益)//第i天卖出状态的最大收益=max(第i-1天卖出状态的最大收益(第i天无操作),第i-1天买入状态,第i天卖出(股票价格及为第i天可得收益))dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);//第i天是买入状态,则:可能是第i-1天是买入状态,持续到今天;可能是第i-1天是卖出状态,第i天买入(当前收益为:第i-1天卖出的收益-第i天的股票价格)//第i天买入状态的最大收益=max(第i-1天买入状态最大收益(第i天无操作),第i-1天卖出状态,第i天买入(需要由第i-1天最大收益-第i天的股票价格))dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);}return dp[le - 1][0];}public static void main(String[] args) {int[] prices = {7, 1, 5, 3, 6, 4};Arraygupiao2_2 arr = new Arraygupiao2_2();int profit = arr.maxProfit(prices);System.out.println(profit);}
}

算法分析
时间复杂度:O(n)O(n)O(n)
空间复杂度:O(n)O(n)O(n)
提交截图

Leetcode小白试炼(20200823 买卖股票的最佳时机 Ⅱ )相关推荐

  1. LeetCode刷题记录——买卖股票的最佳时机

    目录 1. 买卖股票的最佳时机 2. 买卖股票的最佳时机II 相信许多小伙伴在笔试和面试的时候会经常遇到 买卖股票的最佳时机的相关题目,看了这篇文章,你将会一次性掌握该系列题目的解法. 废话不多说,且 ...

  2. <LeetCode天梯>Day004 买卖股票的最佳时机 II(DP动态规划法) | 初级算法 | Python

    今天1024程序员节,车神哥在这里恭祝各位节日快乐,发量惊人,财务自由,从不加班!!!~ 今天依旧和车神哥一起来提升自己的Python编程和面试能力吧,刷天梯~ 以下为我的天梯积分规则: 每日至少一题 ...

  3. LeetCode(122)——买卖股票的最佳时机 II(JavaScript)

    给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多笔交易(你必须在再次 ...

  4. LeetCode第121题 买卖股票的最佳时机

    给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股票前卖出股票. 示例 ...

  5. LeetCode(121)——买卖股票的最佳时机(JavaScript)

    给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股票前卖出股票. 示例 ...

  6. 【LeetCode笔记】121. 买卖股票的最佳时机 / 剑指 Offer 63. 股票的最大利润(Java、动态规划)

    文章目录 题目描述 代码 & 思路 初版代码 更新啦-优化代码 再次更新 题目描述 讲道理,一眼dp 代码 & 思路 时间复杂度O(n),不过可改进的地方还多,跑出来大概6ms. 初版 ...

  7. 【LeetCode股票买卖系列:714. 买卖股票的最佳时机含手续费 | 暴力递归=>记忆化搜索=>动态规划】

  8. leetcode - 121.买卖股票的最佳时机

    121.买卖股票的最佳时机 ------------------------------------------ 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成 ...

  9. My Eighty-seventh Page - 买卖股票的最佳时机 - By Nicolas

    这篇page是针对leetcode上的188.买卖股票的最佳时机Ⅳ所写的.小尼先简单的说明一下这道题的意思,就是我们给定一个整数数组prices,它的第i个元素prices[i]是一支给的股票在第i天 ...

最新文章

  1. C++ Primer 读书笔记 (1)
  2. Apache的Rewrite规则详细介绍
  3. 与或非逻辑符号_理解FPGA的基础知识——逻辑电路
  4. tf.device()指定tensorflow运行的GPU或CPU设备
  5. Python os.path() 模块 详解 附算例
  6. 25 个在 Web 中嵌入图表的免费资源
  7. Solr学习总结(一)Solr介绍
  8. [Vue.js] 基础 -- Vue简介
  9. VS附加依赖项以及Opencv配置问题
  10. [学习笔记]数据库设计概览
  11. 经典神经网络 -- FPN : 设计原理与pytorch实现
  12. 单台主机一键编译部署LAMP+wordpress+discuz系统的shell脚本
  13. 模拟电子技术基础:基本放大电路
  14. html5制作当当图书榜页面,当当图书.html
  15. 亿图图示+linux版本,亿图图示linux版下载
  16. dns 性能测试 dnsperf
  17. PicPick 5.1.3 中文版,一个全功能的屏幕截图工具,图像编辑器,颜色选择器
  18. 60个可爱的云图案设计,激发你的灵感
  19. 【每日笔记】:layui表单checkbox设为必选
  20. 逐行讲解CRF实现命名实体识别(NER)

热门文章

  1. 国内各大企业开工时间出炉,这些公司有点狠...
  2. Linux网络不通Tcpdump抓包提示:ICMP host *** unreachable - admin prohibited
  3. 利用百度AI开放平台识别干部培训网登录验证码
  4. 跨平台数据库ODB实战2-运行Hello Example
  5. 裁剪图片怎么弄?这几种裁剪图片方法学起来
  6. Ubuntu18.04 LimeSDR GSM实验
  7. 关于thymeleaf组件中th:each的遍历功能出现的问题
  8. 【QA】Python代码调试之解决Segmentation fault (core dumped)问题
  9. 程序员的修炼-从优秀到卓越札记:阅读之美
  10. 市值超英特尔,英伟达如何“兴风作浪”?