【问题标题】:Best time to buy and Sell Stock- Another approach in Python [closed]买卖股票的最佳时间-Python中的另一种方法[关闭]
【发布时间】:2020-07-02 04:21:12
【问题描述】:

问题-假设您有一个数组,其中 ith 元素是给定股票在 dayi 的价格。

如果您最多只能完成一次交易(即买入并卖出一股股票),请设计一种算法来找到最大利润。

请注意,您不能在买入股票之前先卖出股票。

示例 1:

Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
             Not 7-1 = 6, as selling price needs to be larger than buying price.

示例 2:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

我相信这个问题可以使用动态编程来解决,在继续简单地解决这个问题之前,我尝试使用我自己的方法来解决这个问题。 我确实检查了蛮力算法并意识到我的方法与蛮力不相似

public class Solution {
    public int maxProfit(int prices[]) {
        int maxprofit = 0;
        for (int i = 0; i < prices.length - 1; i++) {
            for (int j = i + 1; j < prices.length; j++) {
                int profit = prices[j] - prices[i];
                if (profit > maxprofit)
                    maxprofit = profit;
            }
        }
        return maxprofit;
    }
}

这是我的方法

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        res=0
        if not prices:
            return 0
        idx=prices.index(min(prices))
        value=min(prices)
        try:
            for i in range (idx+1,len(prices)):
                res=max(res,prices[i]-value)
        except IndexError :
            return 0
        return res    

我的代码通过了示例测试用例和 143/200 用例,但这次失败了。

Input: [2,4,1]
Output: 0
Expected: 2

如何改进我的代码?我怎样才能使这种方法起作用?或者如果这种方法完全错误,请详细说明。

我相信我的方法的时间复杂度比蛮力要好,因此,努力使这段代码工作;稍后检查动态编程方法

【问题讨论】:

  • 该示例的问题是最低价格在索引 2 中,因此您的 for 循环什么也不做,因为它只查看列表中最低价格之后的价格。
  • 每个 Stack Overflow 问题都应该是关于一个狭隘的、具体的问题,并考虑到对该问题而言并非必不可少的所有问题。我们不允许在这里提出一般改进的请求。请参阅codereview.meta.stackexchange.com/questions/5777/…,了解我们的规则与姊妹网站 Code Review 的规则之间的差异(尽管他们要求问题是关于工作代码的,所以现在这在那儿是不可接受的)。

标签: python algorithm time-complexity dynamic-programming


【解决方案1】:
def max_profit(prices):
    if not prices:
        return 0

    max_prof = 0
    min_price = prices[0]

    for i in range(1, len(prices)):
        if prices[i] < min_price:
            min_price = prices[i]
        max_prof = max(max_prof, prices[i] - min_price)
    return max_prof

输出:

print(max_profit([1, 2, 3, 4, 5]))
print(max_profit([5, 4, 3, 2, 1]))
print(max_profit([3, 1, 2, 4, 5]))
print(max_profit([7, 1, 5, 3, 6, 4]))
print(max_profit([7, 6, 4, 3, 1]))
print(max_profit([2, 4, 1]))
4
0
4
5
0
2

【讨论】:

    【解决方案2】:

    对于这个问题,最有效的算法是 O(N) 时间和 O(1) 空间,它不能再高效了,因为这里我们必须至少访问每个元素一次:

    class Solution:
        def maxProfit(self, prices):
            if not prices:
                return 0
    
            max_price = 0
            min_price = float('inf')
            for i in range(len(prices)):
                if prices[i] < min_price:
                    min_price = prices[i]
                if prices[i] > max_price:
                    max_price = max(max_price, prices[i] - min_price)
            return max_price
    

    参考

    • 有关其他详细信息,您可以查看Discussion Board。那里有大量公认的解决方案、解释、多种语言的高效算法,以及时间/空间复杂度分析。

    【讨论】:

    • 好的。谢谢,我会记住的
    【解决方案3】:

    这个问题不需要动态规划。您想找到x[i] 的最大值 - (最高 i 的最低价格)。因此,要找到卖出时间,您只需评估(如果您正在处理 numpy 数组)sell = np.argmax(x- np.minumum.accumulate(x)) 对于买入时间,您需要 `np.argmin(x[:sell])

    如果您使用的是原版 python(没有 numpy),只需实现累积的 minimumargmin/argmax(非常简单)。

    【讨论】:

      【解决方案4】:

      我不擅长python,但我可以告诉你我将如何做java。

      public int maxProfit(int[] prices) {
          int n = prices.length;
          if(n==0) return 0;
          int[] L = new int[n];
          int[] R = new int[n];
          L[0]=prices[0];
          for(int i=1;i<n;i++){
              L[i]=Math.min(L[i-1], prices[i]);
          }
          R[n-1]=prices[n-1];
          for(int i=n-2;i>=0;i--){
              R[i]=Math.max(R[i+1], prices[i]);
          }
          int max=Integer.MIN_VALUE;
          for(int i=0;i<n;i++){
              max = Math.max(max, R[i]-L[i]);
          }
          return max;
      }
      

      这种方法基本上是基于捕获雨水问题。

      【讨论】:

      • 哦,是的..捕获雨水问题是一个更好的方法。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      • 2021-06-07
      • 1970-01-01
      • 2020-10-04
      • 2018-03-20
      • 1970-01-01
      • 2020-05-06
      相关资源
      最近更新 更多