How to maximize returns when you can only buy and sell stocks twice

See the original title: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/

Given a list of stock prices (sorted by date), how to maximize returns given that you can buy and sell at most twice;

For example: 1, 2, 1, 3, 0, 4;

The maximum profit is 6, buy on the third day, sell on the fourth day, buy on the fifth day, and sell on the sixth day;

First use the algorithm of dynamic programming; use f(i, j) to represent the maximum profit when only buying and selling once from the i-th (from 0) day to the j-th day; then, to calculate the income of two transactions, you only need to find one day k, so that f(0, k) + f(k + 1, n - 1) is the largest;

f(i, j) is the maximum of the following equations:

  1. 0; If the price on the i-th day is higher than the price on the j-th day, the profit from not trading is the greatest;
  2. prices(j) - prices(i); the price of day j minus the price of day i;
  3. f(i + 1, j); No transaction on day i, maximum profit from day i + 1 to day j;
  4. f(i, j - 1); 

The following is the main implementation code:

func maxProfit(prices []int) int {
	prices = compact1(prices)
	prices = compact2(prices)
	if len(prices) == 0 {
		return 0
	}
	n := len(prices)
	fx := make([][]int, n)

	for i := range fx {
		fx[i] = make([]int, n)
	}

	for k := 1; k < n; k++ {
		for i := 0; i+k < n; i++ {
			j := i + k
			fx[i][j] = max(0, prices[j]-prices[i])
			if k == 1 {
				continue
			}
			fx[i][j] = max(fx[i][j], fx[i+1][j])
			fx[i][j] = max(fx[i][j], fx[i][j-1])
		}
	}

	r := fx[0][n-1]
	for k := 1; k < n-1; k++ {
		if fx[0][k]+fx[k][n-1] > r {
			r = fx[0][k] + fx[k][n-1]
		}
	}

	return r
}

 

Because there may be a lot of data, the data is compressed before processing, and only those data that will affect the income are retained; for example, 1, 2, 3, 4, only 1, 4 need to be retained; 4, 3, 2, 1 only Need to keep 4, 1;

The time complexity of this algorithm is o(n * n), and the space also requires o(n * n);

But this topic has a more streamlined, faster and more elegant algorithm, which is impressive; for specific discussions, please refer to https://discuss.leetcode.com/topic/32288/2ms-java-dp-solution;

The current state is represented using the following four values:

firstBuy: The income from buying the stock for the first time; this value is expressed as the negative number of the price, so the lower the price, the higher the income;

firstSell: the profit from the first sale of the stock; firstSell = max(firstSell, firstBuy + currentPrice); the price at the time of selling (plus) the profit at the time of the first purchase (negative value);

secondBuy: The income when the stock is bought for the second time; secondBuy = max(secondBuy, firstSell - currentPrice);

secondSell: The income when the second sell; secondSell = max(secondSell, secondBuy + currentPrice);

 Code:


func maxProfit2(prices []int) int {
	firstBuy, firstSell := math.MinInt32, 0
	secondBuy, secondSell := math.MinInt32, 0

	for _, price := range prices {
		if firstBuy < -price {
			firstBuy = -price
		}

		if firstSell < firstBuy+price {
			firstSell = firstBuy + price
		}

		if secondBuy < firstSell-price {
			secondBuy = firstSell - price
		}

		if secondSell < secondBuy+price {
			secondSell = secondBuy + price
		}
	}

	return secondSell
}

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325737276&siteId=291194637