在股票交易中,买方在未来的某个日期购买股票并出售。给定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)