📌  相关文章
📜  通过最多买卖K股获得最大利润|贪婪的方法

📅  最后修改于: 2021-05-17 18:57:40             🧑  作者: Mango

在股票交易中,买方在未来的某个日期购买股票并出售。给定N天的股票价格,交易者最多可以进行K笔交易,而新交易只能在前一次交易完成后才能开始。任务是找出股票交易者可以赚到的最大利润。

例子:

请参考本文了解动态编程方法

方法:此方法说明如何使用贪婪方法解决此问题:

  • 在股价上涨之前找到最低价格,然后在股价再次下跌之前找到最高价格。这些分别作为当前的买入和卖出价格。
  • 将这些买卖价格与上一交易的价格进行比较。如果当前购买价格低于上一交易的价格,请删除该交易,并考虑具有被移除交易的当前购买价格和销售价格的新交易,以增加利润,并在可以通过以下方式进一步增加利润的情况下继续进行交易:当前的购买价格。
  • 同样,比较售价并在可能的情况下增加利润。
  • 遍历所有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)