假设你有一个数组prices,长度为n,其中prices[i]是某只股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益
1. 你可以多次买卖该只股票,但是再次购买前必须卖出之前的股票
2. 如果不能获取收益,请返回0
3. 假设买入卖出均无手续费
数据范围:
,
要求:空间复杂度
,时间复杂度 )
进阶:空间复杂度
,时间复杂度
[8,9,2,5,4,7,1]
7
在第1天(股票价格=8)买入,第2天(股票价格=9)卖出,获利9-8=1 在第3天(股票价格=2)买入,第4天(股票价格=5)卖出,获利5-2=3 在第5天(股票价格=4)买入,第6天(股票价格=7)卖出,获利7-4=3 总获利1+3+3=7,返回7
[5,4,3,2,1]
0
由于每天股票都在跌,因此不进行任何交易最优。最大收益为0。
[1,2,3,4,5]
4
第一天买进,最后一天卖出最优。中间的当天买进当天卖出不影响最终结果。最大收益为4。
总天数不大于200000。保证股票每一天的价格在[1,100]范围内。
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 计算最大收益 * @param prices int整型一维数组 股票每一天的价格 * @return int整型 */ public int maxProfit (int[] prices) { // write code here int profits = 0; int len = prices.length; for(int i =1;i<len;i++){ if(prices[i]>prices[i-1]){ profits+=prices[i]-prices[i-1]; //逢高卖出 } } return profits; } }
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 计算最大收益 * @param prices int整型vector 股票每一天的价格 * @return int整型 */ int maxProfit(vector<int>& prices) { int res=0; for(int i=1;i<prices.size();i++) { if(prices[i]>prices[i-1]) { res+=prices[i]-prices[i-1]; } } return res; } };
function maxProfit( prices ) { let curr=prices[0] let res=0 for(let i=1;i<prices.length;i++){ if(prices[i]>curr){ res+=prices[i]-curr curr=prices[i] }else{ curr=prices[i] } } return res }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 计算最大收益 * @param prices int整型一维数组 股票每一天的价格 * @return int整型 */ public int maxProfit (int[] prices) { //持有股票1和不持有股票0两种状态,第0天和第1,2,3...第prices.length天 int[][] dp = new int[2][prices.length + 1]; //第0天未持有股票,收益为0 dp[0][0] = 0; //第0天持有股票,不存在,收益为负无穷 dp[1][0] = Integer.MIN_VALUE; for (int i = 1; i <= prices.length; i++) { //第i天未持有股票,两个可能: //1.在前面i-1天都持有,第i天卖掉了,卖掉价值增加。dp[1][i - 1] + prices[i - 1] //2.到当前为止都为未持有,维持第i-1天的结果。dp[0][i - 1] dp[0][i] = Math.max(dp[0][i - 1], dp[1][i - 1] + prices[i - 1]); //第i天持有股票,两个可能: //1.在前面i-1天都未持有,第i天买入了,总价值减少。dp[0][i - 1] - prices[i - 1] //2.到当前为止都为持有,维持第i-1天的结果。dp[1][i - 1] dp[1][i] = Math.max(dp[1][i - 1], dp[0][i - 1] - prices[i - 1]); } //获取最后一天卖掉的最大值 return dp[0][prices.length]; } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 计算最大收益 * @param prices int整型一维数组 股票每一天的价格 * @return int整型 */ public int maxProfit (int[] prices) { // write code here int profit=0; for(int i=1;i<prices.length;i++){ if(prices[i]>prices[i-1]){ profit+=prices[i]-prices[i-1]; } } return profit; } }
int maxProfit(vector<int>& prices) { //完成无限次的交易 int size=prices.size(); vector<vector<int>> dp(size,vector<int>(2,0));//1=持有 0=未持有 dp[0][0]=0; dp[0][1]=-prices[0]; for(int i=1;i<size;++i){ dp[i][0]=std::max(dp[i-1][0],dp[i-1][1]+prices[i]); dp[i][1]=std::max(dp[i-1][1],dp[i-1][0]-prices[i]); } return dp[size-1][0]; }
function maxProfit( prices ) { // write code here let profit = 0 for(let i = 1; i < prices.length; i++) { if(prices[i] > prices[i - 1]) { profit += prices[i] - prices[i - 1] } } return profit }
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 计算最大收益 * @param prices int整型vector 股票每一天的价格 * @return int整型 */ int maxProfit(vector<int>& prices) { // 时间复杂度O(N),空间复杂度O(N) if (prices.empty()) return 0; int dp[2][prices.size()]; dp[0][0] = -prices[0], dp[1][0] = 0; for (int i = 1; i < prices.size(); ++i) { dp[0][i] = max(dp[0][i - 1], dp[1][i - 1] - prices[i]); dp[1][i] = max(dp[1][i - 1], dp[0][i - 1] + prices[i]); } return dp[1][prices.size() - 1]; } };
class Solution: def maxProfit(self , prices: List[int]) -> int: n = len(prices) #dp[i][0]表示某一天不持股到该天为止的最大收益,dp[i][1]表示某天持股,到该天为止的最大收益 dp = [[0] * 2 for i in range(n)] #第一天不持股,总收益为0 dp[0][0] = 0 #第一天持股,总收益为减去该天的股价 dp[0][1] = -prices[0] #遍历后续每天,状态转移 for i in range(1, n): # 第i天不持股有两种情况,第一种昨天就没有买股票,第二种昨天卖出了股票(这里一直保存最大收益,整个过程下来相当于只买了一次) dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]) # 第i天持股有两种情况,第一种昨天就持股,第二种昨天不持股,但是今天买入了(这里相当于寻找最最小值了) dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]) #最后一天不持股,到该天为止的最大收益 return dp[n - 1][0]
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 计算最大收益 * @param prices int整型一维数组 股票每一天的价格 * @return int整型 */ public int maxProfit (int[] prices) { // write code here // 状态定义dp[i][0]:表示在第i天不持有股票最大收益;dp[i][1]表示在第i天持有股票最大收益 int dp[][] = new int[prices.length][2]; // 初始化 dp[0][0] = 0; dp[0][1] = -prices[0]; // 遍历,状态转移 for(int i = 1;i < prices.length;i++){ dp[i][0] = Math.max(dp[i - 1][0],dp[i - 1][1] + prices[i]); dp[i][1] = Math.max(dp[i - 1][1],dp[i - 1][0] - prices[i]); } return dp[prices.length - 1][0]; } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 计算最大收益 * @param prices int整型一维数组 股票每一天的价格 * @return int整型 */ public int maxProfit (int[] prices) { // write code here int res = 0; for(int i = 1; i < prices.length; i++) { int gap = prices[i] - prices[i - 1]; if(gap > 0) res += gap; } return res; } }不明白为啥是medium题,感觉股票一才应该是medium
很容易想出这道题的状态转移方程
func MaxProfitBM81(prices []int) int { a, b := -prices[0], 0 for i := 2; i <= len(prices); i++ { a, b = Max(a, b-prices[i-1]), Max(b, a+prices[i-1]) } return b }
class Solution { public: int maxProfit(vector<int>& prices) { vector<int> dp(prices.size(), 0); for(int i=1;i<prices.size(); ++i){ dp[i] = max(dp[i-1], dp[i-1] + prices[i] - prices[i-1]); } return dp.back(); } };