在股票交易中,买方买入股票并在未来日期卖出。给定N天的股票价格,交易者最多可以进行K笔交易,新的交易只能在前一笔交易完成后开始。任务是找出股票交易者可能获得的最大利润。
例子:
Input: prices[] = {10, 22, 5, 75, 65, 80}, K = 2
Output: 87
Explanation: The trader performs 2 transactions, the first of which is by purchasing at price 10 and selling it at price 22 followed by a purchase and sale at price 5 and 80 respectively. Thus, the profit earned is 87.
Input: prices[] = {12, 14, 17, 10, 14, 13, 12, 15}, K = 3
Output: 12
Explanation: First transaction involves purchase and sell at prices 12 and 17 respectively. Second one is a purchase at price 10 and sell at 14 followed by a purchase at 12 and sell at 15. Thus, the total profit earned is 12.
动态规划方法请参考这篇文章
方法:这种方法展示了如何使用贪婪方法解决这个问题:
- 找出股价上涨之前的最低价格,然后是价格再次下跌之前的最高价格。这些分别作为当前的买入价和卖出价。
- 将这些买卖价格与之前交易的价格进行比较。如果当前买入价低于前一交易,则移除该交易并考虑以移除交易的当前买入价和卖出价进行新交易以增加利润并继续,只要利润可以进一步增加当前的购买价格。
- 同样,比较销售价格并尽可能增加利润。
- 遍历所有N个价格后,加上最高的K个利润。如果交易次数小于K ,则计算所有交易的利润总和。
下面的代码是上述方法的实现:
C++14
// C++ program to find out maximum profit by
// buying and selling a share at most k times
// given the stock price of n days
#include
using namespace std;
// Function to return the maximum profit
int maxProfit(int n, int k, int prices[])
{
int ans = 0, buy = 0, sell = 0;
stack > transaction;
priority_queue profits;
while (sell < n) {
buy = sell;
// Find the farthest decreasing span
// of prices before prices rise
while (buy < n - 1
&& prices[buy] >= prices[buy + 1])
buy++;
sell = buy + 1;
// Find the farthest increasing span
// of prices before prices fall again
while (sell < n
&& prices[sell] >= prices[sell - 1])
sell++;
// Check if the current buying price
// is greater than that
// of the previous transaction
while (!transaction.empty()
&& prices[buy]
< prices[transaction.top().first]) {
pair p = transaction.top();
// Store the profit
profits.push(prices[p.second - 1]
- prices[p.first]);
// Remove the previous transaction
transaction.pop();
}
// Check if the current selling price is
// less than that of the previous transactions
while (!transaction.empty()
&& prices[sell - 1]
> prices[transaction.top().second - 1]) {
pair p = transaction.top();
// Store the new profit
profits.push(prices[p.second - 1]
- prices[buy]);
buy = p.first;
// Remove the previous transaction
transaction.pop();
}
// Add the new transactions
transaction.push({ buy, sell });
}
// Finally store the profits
// of all the transactions
while (!transaction.empty()) {
profits.push(
prices[transaction.top().second - 1]
- prices[transaction.top().first]);
transaction.pop();
}
// Add the highest K profits
while (k && !profits.empty()) {
ans += profits.top();
profits.pop();
--k;
}
// Return the maximum profit
return ans;
}
// Driver code
int main()
{
int k = 3;
int prices[] = { 1, 12, 10, 7,
10, 13, 11, 10,
7, 6, 9 };
int n = sizeof(prices) / sizeof(prices[0]);
cout << "Maximum profit is "
<< maxProfit(n, k, prices);
return 0;
}
Java
// Java program to find out maximum profit
// by buying and selling a share at most k
// times given the stock price of n days
import java.util.*;
import java.lang.*;
class GFG{
// Function to return the maximum profit
static int maxProfit(int n, int k,
int prices[])
{
int ans = 0, buy = 0, sell = 0;
Stack transaction = new Stack<>();
PriorityQueue profits = new PriorityQueue<>();
while (sell < n)
{
buy = sell;
// Find the farthest decreasing span
// of prices before prices rise
while (buy < n - 1 &&
prices[buy] >= prices[buy + 1])
buy++;
sell = buy + 1;
// Find the farthest increasing span
// of prices before prices fall again
while (sell < n &&
prices[sell] >= prices[sell - 1])
sell++;
// Check if the current buying price
// is greater than that of the
// previous transaction
while (!transaction.isEmpty() &&
prices[buy] <
prices[transaction.peek()[0]])
{
int[] p = transaction.peek();
// Store the profit
profits.add(prices[p[1] - 1] -
prices[p[0]]);
// Remove the previous transaction
transaction.pop();
}
// Check if the current selling price
// is less than that of the previous
// transactions
while (!transaction.isEmpty() &&
prices[sell - 1] >
prices[transaction.peek()[1] - 1])
{
int[] p = transaction.peek();
// Store the new profit
profits.add(prices[p[1] - 1] -
prices[buy]);
buy = p[0];
// Remove the previous transaction
transaction.pop();
}
// Add the new transactions
transaction.push(new int[]{ buy, sell });
}
// Finally store the profits
// of all the transactions
while (!transaction.isEmpty())
{
profits.add(
prices[transaction.peek()[1] - 1] -
prices[transaction.peek()[0]]);
transaction.pop();
}
// Add the highest K profits
while (k > 0 && !profits.isEmpty())
{
ans += profits.peek();
profits.poll();
--k;
}
// Return the maximum profit
return ans;
}
// Driver code
public static void main(String[] args)
{
int k = 3;
int prices[] = { 1, 12, 10, 7, 10, 13,
11, 10, 7, 6, 9 };
int n = prices.length;
System.out.println("Maximum profit is " +
maxProfit(n, k, prices));
}
}
// This code is contributed by offbeat
Python3
# Python3 program to find out maximum profit by
# buying and selling a share at most k times
# given the stock price of n days
# Function to return the maximum profit
def maxProfit(n, k, prices):
ans = 0
buy = 0
sell = 0
# stack
transaction = []
# priority queue
profits = []
while (sell < n):
buy = sell
# Find the farthest decreasing span
# of prices before prices rise
while (buy < n - 1 and prices[buy] >= prices[buy + 1]):
buy += 1
sell = buy + 1
# Find the farthest increasing span
# of prices before prices fall again
while (sell < n and prices[sell] >= prices[sell - 1]):
sell += 1
# Check if the current buying price
# is greater than that
# of the previous transaction
while (len(transaction) !=0 and prices[buy] < prices[transaction[len(transaction)-1][0]]):
p = transaction[len(transaction)-1]
# Store the profit
profits.append(prices[p[1] - 1] - prices[p[0]])
# Remove the previous transaction
transaction.remove(transaction[len(transaction)-1])
# Check if the current selling price is
# less than that of the previous transactions
profits.sort(reverse=True)
while (len(transaction)!=0 and prices[sell - 1] > prices[transaction[len(transaction)-1][1] - 1]):
p = transaction[len(transaction)-1]
# Store the new profit
profits.append(prices[p[1] - 1] - prices[buy])
buy = p[0]
# Remove the previous transaction
transaction.remove(transaction[len(transaction)-1])
# Add the new transactions
transaction.append([buy, sell])
profits.sort(reverse=True)
# Finally store the profits
# of all the transactions
while (len(transaction) != 0):
profits.append(prices[transaction[len(transaction)-1][1]- 1]-prices[transaction[len(transaction)-1][0]])
transaction.remove(transaction[len(transaction)-1])
profits.sort(reverse=True)
# Add the highest K profits
while (k!=0 and len(profits)!=0):
ans += profits[0]
profits.remove(profits[0])
k -= 1
# Return the maximum profit
return ans
# Driver code
if __name__ == '__main__':
k = 3
prices = [1, 12, 10, 7,10, 13, 11, 10,7, 6, 9]
n = len(prices)
print("Maximum profit is",maxProfit(n, k, prices))
# This code is contributed by Surendra_Gangwar
Maximum profit is 20
时间复杂度: O(N * log N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。