Loading

LeetCode121.买卖股票的最佳时机

题目

给定一个数组 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 <= prices.length <= 105

0 <= prices[i] <= 104

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题方法

暴力破解

双重循环判断获取最大利润
时间复杂度O(n^2)空间复杂度O(1)
在LeetCode中执行会超时

一次遍历(贪心)

使用一次循环 
循环内判断当前股票价格是否低于历史最低价格,如果低于历史最低就更新最低价格
然后拿当前价格减去历史最低价格,获取最大利润
时间复杂度O(n)空间复杂度O(1)

动态规划

参考:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/solution/121-mai-mai-gu-piao-de-zui-jia-shi-ji-by-leetcode-/
个人理解在代码注释
时间复杂度O(n)空间复杂度O(1)

代码

// 动态规划,时间复杂度O(n),空间复杂度O(1)
func maxProfit(prices []int) int {
	length := len(prices)
	if length == 0{return 0}
	// 初始化动态数组
	dp := make([][]int,length)
	for i := 0;i < length;i++{
		dp[i] = make([]int,2)
	}
	// dp[0][0]初始化,假设本金为0,第一天买入股票
	// dp[x][0]在后续的循环中保存当前最低的股票价格
	dp[0][0] = -prices[0]
	// dp[0][1]初始化,表示第一天不买股票最大利润
	// dp[x][1]在后续的循环中保存当前股票价格能获取的最大利润
	dp[0][1] = 0
	var max func(a,b int) int
	max = func(a, b int) int {
		if a > b{return a}
		return b
	}
	for i := 1;i < length;i++{
		// 第i天持有股票可以有两种状态
		// 1.保持现状,仍旧持有昨天的股票,即:dp[i-1][0]
		// 1.第i天买入股票,所得现金就是:-prices[i]
		// 最终我们要通过比较两者,获取买入价格最低的,也就是-prices[i]最大的值
		dp[i][0] = 	max(dp[i-1][0],-prices[i])
		// 第i天不持有股票也可以有两种状态
		// 1.第i-1天就不持有股票,保持现状,所得金额就是昨天不持有股票所得现金:dp[i-1][i](可以理解为是前一天把股票卖出去所得的金额)
		// 2.第i天把股票卖出去,所得金额就是当前股票价格+dp[i-i][0] (这里为什么是加,因为我们的dp[i][0]是买入股票的价格负数,所以其实就相当于当前价格-买入价格)
		// 最终我们要通过比较两者,获取我们能得到的最大利润
		dp[i][1] = max(dp[i-1][1],dp[i-1][0]+prices[i])
	}
	return dp[length-1][1]
}

// 遍历一次(贪心),时间复杂度O(n),空间复杂度O(1)
func maxProfit2(prices []int) int {
	// 保存历史最低价格
	minValue := math.MaxInt64
	// 能够获取的最大利润
	maxValue := 0
	for i := 0;i < len(prices);i++{
		// 当前股票价格是否低于历史最低价格
		if prices[i] < minValue{
			minValue = prices[i]
			// 当前卖出股票利润是否最大
		}else if prices[i] - minValue > maxValue{
			maxValue = prices[i] - minValue
		}
	}
	return maxValue
}
posted @ 2021-08-26 15:19  励码万言  阅读(27)  评论(0编辑  收藏  举报