js(108)~122. 买卖股票的最佳时机 II

145 阅读3分钟

122. 买卖股票的最佳时机 II

image.png

具体思路见题解,分为二维数组和一维滚动数组

方法一 二维数组

var maxProfit = function (prices) {

	const dp = new Array(prices.length).fill(0).map(v => [0, 0]);

	// dp[i][0] 表示第 i 天交易完后手里 没有 股票的最大利
	// dp[i][1] 表示第 i 天交易完后手里 有 股票的最大利
	dp[0][0] = 0;
	dp[0][1] = 0 - prices[0];

	// 主要有两个状态决定
	// 1 如果第i天不持有股票即dp[i][0]的情况, 依然可以由两个状态推出来
	// 第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][0]
	// 第i天卖出股票,所得现金就是按照今天股票佳价格卖出后所得现金即:prices[i] + dp[i - 1][1]
	// 2 如果第i天持有股票即dp[i][1], 那么可以由两个状态推出来
	// 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][1]
	// 第i天买入股票,所得现金就是昨天不持有股票的所得现金减去 今天的股票价格 即:dp[i - 1][0] - prices[i]

	for (let 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]);
	}

	// 根据状态定义我们可以知道第 00 天交易结束的时候 dp[0][0]=0,dp[0][1]=−prices[0]。因此,我们只要从前往后依次计算状态即可。由于全部交易结束后,持有股票的收益一定低于不持有股票的收益
	return dp[prices.length - 1][0]
};

方法二 一维滚动数组

下面直接是从二维数组,删除i用一个一维数组表示,因为这个一维数组只有2个值,所以可以进一步优化有dp0, dp1两个字段来表示,道理是一样所以注释我没有改变

var maxProfit = function (prices) {

	const dp = new Array(2);

	// dp[i][0] 表示第 i 天交易完后手里 没有 股票的最大利
	// dp[i][1] 表示第 i 天交易完后手里 有 股票的最大利
	dp[0] = 0;
	dp[1] = 0 - prices[0];

	// 主要有两个状态决定
	// 1 如果第i天不持有股票即dp[i][0]的情况, 依然可以由两个状态推出来
	// 第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][0]
	// 第i天卖出股票,所得现金就是按照今天股票佳价格卖出后所得现金即:prices[i] + dp[i - 1][1]
	// 2 如果第i天持有股票即dp[i][1], 那么可以由两个状态推出来
	// 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][1]
	// 第i天买入股票,所得现金就是昨天不持有股票的所得现金减去 今天的股票价格 即:dp[i - 1][0] - prices[i]

	for (let i = 1; i < prices.length; i++) {
		dp[0] = Math.max(dp[0], dp[1] + prices[i]);
		dp[1] = Math.max(dp[1], dp[0] - prices[i]);
	}

	// 根据状态定义我们可以知道第 00 天交易结束的时候 dp[0][0]=0,dp[0][1]=−prices[0]。因此,我们只要从前往后依次计算状态即可。由于全部交易结束后,持有股票的收益一定低于不持有股票的收益
	return dp[0]
};