Best Time to Buy and Sell Stock

题目等级:Easy

题目描述:

Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Note that you cannot sell a stock before you buy one.

Example 1:

Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Not 7-1 = 6, as selling price needs to be larger than buying price.

Example 2:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

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


解题思路:

  对于本题,有以下两种解法:

  解法一:Brute Force暴力解法

  由于限制只允许一次交易,那么一个最直观的解法就是对每一天,都依次遍历它之后的所有可能卖出的情况,记录最大值,最后进行比较得出最终结果。很显然这是一个二重循环,时间复杂度为O(n^2),空间复杂度:O(1)。

  换句话说,这也就是将所有可能的买卖情况都穷举出来,然后找最大值。

	public int maxProfit(int[] prices) {
//解法一:蛮力法,找到每一天后续的最大值,比较确定最大利润
//时间复杂度:O(n^2),空间复杂度:O(1)
if(prices==null || prices.length==0)
return 0;
int maxprofit=0;
for(int i=0;i<prices.length;i++){
for(int j=i+1;j<prices.length;j++){ //如果第i天买入,依次判断它之后的每一天卖出的情况
if(prices[j]-prices[i]>maxprofit)
maxprofit=prices[j]-prices[i];
}
}
return maxprofit;
}

  解法二:动态规划法

  暴力法需要二重循环,解法二通过动态规划使得只需要一次遍历即可找到最大值,动态规划适用于多阶段决策过程的最优化问题,明显这里就是一个决定什么时候买和卖出的阶段决策问题。

  如果我们用dp[i]表示从第1天到第i天进行一笔交易能获得的最大收益,用min表示买入时的价格(最低的时候),则dp[i]=max(price[i]-min,dp[i-1]),其中maxProfit是指已经找到的最大收益。

  在求出所有的dp[i]以后我们再找到其中的最大值,即为所求值,由于只需要找到最大值,因此可以合二为一,遍历的过程中顺便求最大值,因此递推公式变为:

dp[i]=max(price[i]-min,maxProfit)

  由于只允许一次交易,所以要想获得最大收益,必须在价格最低的时候买入,最高的时候卖出,但是由于必须先买后卖,所以如果用波形来说,就是要找到一个波峰和波谷,波谷在波峰之前。

![](https://img2018.cnblogs.com/blog/1608161/201907/1608161-20190702101051380-93136565.png)

  在这里,我们只需要维护一个min变量,就可以省去一层循环,代码如下:

	public int maxProfit(int[] prices) {
//解法二:动态规划法:用dp[i]表示第i天卖出的收益,则dp[i]=max(price[i]-min,maxProfit)
//时间复杂度:O(n),空间复杂度:O(1)
if(prices==null || prices.length==0)
return 0;
int len=prices.length;
int maxprofit=0,min=Integer.MAX_VALUE;
for(int i=0;i<len;i++){
if(prices[i]<min) //维护一个最小值
min=prices[i];
else if(prices[i]-min>maxprofit)
maxprofit=prices[i]-min;
}
return maxprofit;
}

总结

  以上两种解法实际上都比较好理解,实际上,暴力法就是我们先确定哪一天买,这样卖出的选择就需要遍历,而动态规划法,我们是先确定哪一天卖,由于题目的特点,那么买的时间就是卖之前的最小值,正好在这个遍历的过程中我们就能把这个最小值记录下来,因此得到了性能的提升。

【LeetCode】121、买卖股票的最佳时机的更多相关文章

  1. 每日一题-——LeetCode(121)买卖股票的最佳时机

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

  2. Java实现 LeetCode 121 买卖股票的最佳时机

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

  3. Leetcode——121. 买卖股票的最佳时机

    题目描述:买卖股票的最佳时机 题目要求求解能获得最大利润的方式? 可以定一个二维数组 d [ len ] [ 2 ] ,其中d[ i ][ 0 ] 表示前i天可以获得的最大利润:d[ i ][ 1 ] ...

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

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

  5. leetcode 121. 买卖股票的最佳时机 JAVA

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

  6. 【每天一题】LeetCode 121. 买卖股票的最佳时机

    开源地址:点击该链接 题目描述 * https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock * 题目描述: * 给定一个数组, ...

  7. [LeetCode] 121. 买卖股票的最佳时机 ☆(动态规划)

    https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/solution/xiang-xi-tong-su-de-si-lu- ...

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

    从下标1开始,维护两个变量,一个是0~i-1中的最低价格low,一个是当前的最高利润res;先更新最高利润,在更新最低价格:应用了贪心算法的基本思想,总是选择买入价格最低的股票,代码如下: 具有最优子 ...

  9. Leetcode之动态规划(DP)专题-121. 买卖股票的最佳时机(Best Time to Buy and Sell Stock)

    Leetcode之动态规划(DP)专题-121. 买卖股票的最佳时机(Best Time to Buy and Sell Stock) 股票问题: 121. 买卖股票的最佳时机 122. 买卖股票的最 ...

  10. LeetCode《买卖股票的最佳时机》系列题目,最详解

    目录 说在前面 引例:只能交易一次 一.动态数组定义 二.状态转移方程 三.初始化 四.优化 无限制买卖 一.动态数组定义 二.状态转移方程 三.初始化 四.优化 交易 2 次,最大利润? 一.动态数 ...

随机推荐

  1. mysql忘记密码如何重置密码,以及修改root密码的三种方法

    1.先将MySQL停止. 命令:systemctl  stop mysqld       #停掉MySQL 命令:systemctl status mysqld         #查看状态 2.然后跳 ...

  2. 你可能用到的Spring工具类?

    现在绝大部分项目都已经拥抱Spring生态,掌握Spring常用的工具类,是非常重要,零成本增加编码效率. 一.常用工具类 ObjectUtils org.springframework.util.O ...

  3. Maven工程构建

    Maven 相关术语: 本地资源库:用来存储项目的依赖库,默认的文件夹是 “.m2” 目录 中央存储库: 用来下载所有项目的依赖库的默认位置 Maven pom.xml: 项目对象模型(Project ...

  4. c# 谷歌动态口令对接

    https://www.cnblogs.com/easyauthor/p/11054869.html Google 身份验证器与两步验证功能配合,可在您登录 Google 帐户时为您平添一重安全保障. ...

  5. EXCL单元格公式——组装SQL用

    ="'"&F3&"'"

  6. 对浏览器如何计算CSS的研究---------------引用

    1. 加载CSS 在构建DOM的过程中,如果遇到link的标签,当把它插到DOM里面之后,就会触发资源加载——根据href指明的链接: 上面的rel指明了它是一个样式文件.这个加载是异步,不会影响DO ...

  7. 30 分钟理解 CORB 是什么

    写在前面 前些日子在调试 bug 的时候,偶然发现这么一个警告: Cross-Origin Read Blocking (CORB) blocked cross-origin response htt ...

  8. [CF1093G]Multidimensional Queries 题解

    前言 DennyQi太巨了! 定义一个点\(a\),\(a_x\)表示\(a\)在第\(x\)维空间上的坐标值 题解 这题的思路珂以说非常巧妙(原谅我又用了这个"珂"), 我们知道 ...

  9. androi自定义自动换行的View(类似网页的标签Tag)

    看来只有礼拜天才有时间写点博客啊,平时只能埋头苦干了.今天在公司加班,遇到一个需求,就是自动换行的TextView,有点像网页的tag标签,点击一下,就自动加上去了,不过这个是根据后台拿来的数据来显示 ...

  10. 大哥带的Orchel数据库时间盲注

    0X01Oracle基于延时的盲注总结 0x00 前言 oracle注入中可以通过页面响应的状态,这里指的是响应时间,通过这种方式判断SQL是否被执行的方式,便是时间盲注: oracle的时间盲注通常 ...