一【题目类别】
- 数组
二【题目难度】
- 简单
三【题目编号】
- 121.买卖股票的最佳时机
四【题目描述】
- 给定一个数组 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。
六【题目提示】
- 1 < = p r i c e s . l e n g t h < = 1 0 5 1 <= prices.length <= 10^5 1<=prices.length<=105
- 0 < = p r i c e s [ i ] < = 1 0 4 0 <= prices[i] <= 10^4 0<=prices[i]<=104
七【解题思路】
- 这道题可以很容易的想到两层 f o r for for循环,但是这样有的用例会超时(时间复杂度为: O ( N 2 ) O(N^2) O(N2),其中 N N N为数组长度),原因是多了很多无谓的判断,所以我们要想怎么减少这些多余的判断,可以更快的找到最大利润
- 所以我们很容易的想到了贪心算法,我们要将利润最大化,也就是说要买入的价钱最少,卖出的价钱最多,但是我们要注意要先买入,在卖出,这个可以通过示例看得更清楚
- 基于这个思路,我们维护maxProfit初始化为0,也就是利润最小是0,minPrice初始化为数组的第一个值,向后搜索时,如果遇到比minPrice还小的值就赋给minPrice表示可以以更小的价钱买入,至于哪天卖出就向后搜索即可,做减法就是利润,如果利润大于我们维护的maxProfit,就更新maxProfit
- 循环结束后返回maxProfit即可
八【时间频度】
- 时间复杂度: O ( N ) O(N) O(N),其中 N N N为数组长度
- 空间复杂度: 1 1 1
九【代码实现】
- Java语言版
package Array;
public class p121_TheBestTimeToBuyAndSellStocks {
public static void main(String[] args) {
int[] prices = {7, 1, 5, 3, 6, 4};
int res = maxProfit(prices);
System.out.println(res);
}
public static int maxProfit(int[] prices) {
int maxProfit = 0;
int minPrice = prices[0];
for (int i = 0; i < prices.length; i++) {
if (prices[i] < minPrice) {
minPrice = prices[i];
}
if ((prices[i] - minPrice) > maxProfit) {
maxProfit = prices[i] - minPrice;
}
}
return maxProfit;
}
}
- C语言版
#include<stdio.h>
int maxProfit(int* prices, int pricesSize)
{
int maxProfit = 0;
int minPrice = prices[0];
for (int i = 0; i < pricesSize; i++)
{
if (prices[i] < minPrice)
{
minPrice = prices[i];
}
if ((prices[i] - minPrice) > maxProfit)
{
maxProfit = prices[i] - minPrice;
}
}
return maxProfit;
}
/*主函数省略*/
十【提交结果】
-
Java语言版
-
C语言版