目录
Leetcode121. 买卖股票的最佳时机
链接:121. 买卖股票的最佳时机 - 力扣(LeetCode)
方法一:暴力解法
1. 思路
因为只能买一次,卖一次,所以这道题目最直观的想法就是暴力找最优间距,外层for loop从头到尾遍历元素,内层for loop从i之后遍历元素;
2. 代码实现
# 方法一:暴力解法
# time:O(N^2);space:O(1)
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
result = 0
for i in range(len(prices)-1):
for j in range(i+1,len(prices)):
result = max(result,prices[j]-prices[i])
return result
3. 复杂度分析
-
时间复杂度:O(N^2)
其中,N为prices数组的长度;两层for loop的时间复杂度为O(N^2);
-
空间复杂度:O(1)
只有result一个变量储存,为常数级的空间复杂度
4. 思考与收获
- 此方法在LeetCode提交中超时了;
方法二:贪心算法
1. 思路
因为股票就买卖一次,那么贪心的想法很自然就是取最左最小值,取最右最大值,那么得到的差值就是最大利润。
2. 代码实现
# 方法二:贪心做法
# time:O(n);space:O(1)
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
low = float("inf")
result = 0
for i in range(len(prices)):
low = min(low,prices[i]) # [0,i]位置的最小值
result = max(result,prices[i]-low) # 目前可以得到的最大利润
return result
3. 复杂度分析
-
时间复杂度:O(N)
其中N为prices的长度;需要遍历一遍整个数组,因此复杂度为O(N);
-
空间复杂度:O(1)
只有两个变量储存信息,分别是low和result,常数级的空间复杂度;
方法三:动态规划
1. 思路
动规五部曲分析如下:
1.1 确定dp数组及下标的含义
-
dp[i][0]
dp[i][0] 表示第i天持有股票所得最多现金 ,这里可能有同学疑惑,本题中只能买卖一次,持有股票之后哪还有现金呢?其实一开始现金是0,那么加入第i天买入股票现金就是 -prices[i], 这是一个负数;
-
dp[i][1]
dp[i][1] 表示第i天不持有股票所得最多现金,注意这里说的是“持有”,“持有”不代表就是当天“买入”!也有可能是昨天就买入了,今天保持持有的状态