zoukankan      html  css  js  c++  java
  • 前沿--股票买卖(亚马逊面试题)

    前沿–股票买卖(亚马逊面试题)

    一.股票买卖

    1.题目描述

    设计一个算法,根据给定的股价走势信息,决定买入和卖出策略,该策略必须保证你的交易获得的利润最大化

    2.暴力枚举法

    检测任何一种可能的买卖组合.例如,第i买进,第j卖出,其中j>i,计算两者差价P(i,j)=S[j]-S[i],并返回计算得到的最大值

    s=[10,4,8,7,9,6,2,5,3]
    
    maxProfit=0
    buyDay=0
    sellDay=0
    
    for i in range(len(s)-1):
        for j in range(i+1,len(s)):
            if s[j]-s[i]>maxProfit:
                maxProfit=s[j]-s[i]
                buyDay=i
                sellDay=j
    
    print("应该在第{0}天买入,第{1}天卖出,最大交易利润为:{2}".format(buyDay+1,sellDay+1,maxProfit))
    
    应该在第2天买入,第5天卖出,最大交易利润为:5
    

    a.性能分析

    假定数组S的长度为n,外层循环运行n次,内层循环走n-i-1.因此算法的时间复杂度为:i=0n1(ni1)=n(n1)/2sum_{i=0}^{n-1}(n-i-1)=n(n-1)/2.也就是说暴力枚举法的算法复杂度为O(n2)O(n^2)

    3.分而治之法

    s分解成两部分。一部分是s的前半部分:s[0:n/2],另一部分是s的后半部分:s[n/2:n],分别计算前半部分和后半部分的最大交易利润,然后在两者中选出最大的一个.但是需要考虑一种跨界情况,那就是最大利润可能实现的方案是:在前半部分的某一天买入,在后半部分的某一天卖出,这种情况我们要在前半部分找到最小值,在后半部分找到最大值,只需要一个循环就可以实现

    def findMaxProfit(s):
        if len(s)<2:
            return [0,0,0]
    
        if len(s)==2:
            if s[1]>s[0]:
                return [0,1,s[1]-s[0]]
    
            else:
                return [0,0,0]
    
        firstHalf=findMaxProfit(s[0:int(len(s)/2)])
        secondHalf=findMaxProfit(s[int(len(s)/2):len(s)])
        finalResult=firstHalf
    
        if secondHalf[2]>firstHalf[2]:
            # 后半部分的交易日期要加上前半部分的天数
            secondHalf[0]+=int(len(s)/2)
            secondHalf[1]+=int(len(s)/2)
            finalResult=secondHalf
        
        # 看最大利润方案是否是在前半部分买入,后半部分卖出
        lowestPrice=s[0]
        highestPrice=s[int(len(s)/2)]
        buyDay=0
        sellDay=int(len(s)/2)
    
        for i in range(0,int(len(s)/2)):
            if s[i]<lowestPrice:
                buyDay=i
                lowestPrice=s[i]
    
        for i in range(int(len(s)/2),len(s)):
            if s[i]>highestPrice:
                sellDay=i
                highestPrice=s[i]
    
        if highestPrice-lowestPrice>finalResult[2]:
            finalResult[0]=buyDay
            finalResult[1]=sellDay
            finalResult[2]=highestPrice-lowestPrice
    
        return finalResult
    
    
    s=[10,4,8,7,9,6,2,5,3]
    
    maxprofit=findMaxProfit(s)
    
    print(maxprofit[0]+1,maxprofit[1]+1,maxprofit[2])
    
    2 5 5
    

    a.分析性能

    算法把一个大问题先分解成两个子问题加以解决,最后再进行一次大循环,因此算法复杂度公式为:

    T(n)=2T(n2)+O(n)T(n)=2T(frac{n}{2})+O(n)

    4.最优解法

    假设最佳交易方案是第N太难卖出,那么很显然,最佳的买入时机就是前N-1天中价格最低的时候,也就是要在s[0:N]中的最小值时买入.如果把最小值记为Min(s[0:N],那么最大利润就是profit=s[N]-Min(s[0:N]).因此我们可以将N从1遍历到n,然后找出最大利润,此时只需遍历数组一次就可以完成

    from IPython.display import Image
    
    Image(filename="./data/1_1.png",width=800)
    

    output_16_0.png

    s=[10,4,8,7,9,6,2,5,3]
    
    maxprofit=0
    leftmin=s[0]
    
    buyDay=0
    sellDay=0
    tmp=0
    
    for i in range(len(s)):
        if s[i]<leftmin:
            leftmin=s[i]
            tmp=i
    
        if s[i]-leftmin>maxprofit:
            maxprofit=s[i]-leftmin
            buyDay=tmp
            sellDay=i
    
    print("应该在第{0}天买入,第{1}天卖出,最大交易利润为:{2}".format(buyDay+1,sellDay+1,maxprofit))
    
    应该在第2天买入,第5天卖出,最大交易利润为:5
    

    a.性能分析

    这种方法只需把数组遍历一次,因此时间复杂度为O(n),它的效率最高

  • 相关阅读:
    Python语言基础03-分支和循环结构
    Python语言基础01-初识Python
    李宏毅深度学习笔记08---Bert、ELMO、GPT
    李宏毅深度学习笔记07---Transformer
    李宏毅深度学习笔记06---word embedding(词嵌入也称词向量)
    李宏毅深度学习笔记05---RNN 循环神经网络02
    李宏毅深度学习笔记04---RNN 循环神经网络01
    李宏毅深度学习笔记03---CNN 卷积神经网络
    李宏毅深度学习笔记02---深度学习的发展历程、3大研究步骤、
    李宏毅深度学习笔记---课程介绍
  • 原文地址:https://www.cnblogs.com/LQ6H/p/12940553.html
Copyright © 2011-2022 走看看