Lintcode 买卖股票的最佳时机 系列问题1,2,3

题目1
假设有一个数组,它的第i个元素是一支给定的股票在第i天的价格。如果你最多只允许完成一次买入和卖出,设计一个算法来找出最大利润。
样例
给出一个数组样例 [3,2,3,1,2], 返回 1

def maxProfit(self, prices):
        # write your code here
        n=len(prices)
        if n==0:
            return 0
        profit=0
        lowest=prices[0]
        for i in range(1,n):
            profit=max(prices[i]-lowest,profit)
            lowest=min(prices[i],lowest)

        return profit    

思路:
只关注历史最低值lowest,在这个点买入,如果今后的某个点prices[i]买入使得profit比之前最大的profit大,那就更新profit。
也就是说不仅要有最小值点,后面还要有一个点使得profit比之前最大的profit大

问题2
假设有一个数组,它的第i个元素是一个给定的股票在第i天的价格。设计一个算法来找到最大的利润。你可以完成尽可能多的交易(多次买卖股票)。然而,你不能同时参与多个交易(你必须在再次购买前出售股票)。

def maxProfit(self, prices):
        # write your code here
        n=len(prices)
        if n==0:
            return 0

        profit=0
        total=0
        for i in range(n-1):
            if prices[i+1]>prices[i]:
                profit=prices[i+1]-prices[i]
                total=total+profit
        return total

思路:
只要相对于前一天有增量,就选择卖出,虽然此时卖出并不是利润最大化的最优解,但是通过累积的增量,比如[1,2,3], 2-1 + 3-2 和3-1的结果是一样的 !

问题3
假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格。设计一个算法来找到最大的利润。你最多可以完成两笔交易。

样例
给出一个样例数组 [6,1,1,4,2,5], 返回 6

def maxProfit(self, prices):
        # write your code here
        n=len(prices)
        if n==0 or n==1:
            return 0

        profit=0
        left_lowest=prices[0]
        left_profit=[0]*n
        for i in range(1,n):
            profit=max(profit,prices[i]-left_lowest)
            left_lowest=min(left_lowest,prices[i])
            left_profit[i]=profit
            print('left_profit',profit)
            print('left_lowest',left_lowest)

        profit=0
        right_profit=[0]*n
        right_highest=prices[n-1]
        for i in range(n-2,-1,-1):
            profit=min(profit,prices[i]-right_highest)
            right_highest=max(right_highest,prices[i])
            right_profit[i]=-profit
            print('right_profit',profit)

        final_profit=0   
        for i in range(n):
            final_profit=max(final_profit,left_profit[i]+right_profit[i])
            #differnt from max subarray, buy and sell can occur on same day
            print('final_profit',final_profit)

        return final_profit

思路:
思路就是扫描线算法,求两个最大不重叠子数组和的思路是一样的,只是这里,可以重叠一个元素(在同一天卖出再买入)。
从左往右的时候记录最小值点,从右往左的时候记录最大值点,另外,从右往左计算的是最小利润,因为是个负值,比如[1,2,4,2,5], 左往右是4-1=3;而右往左是2-5=-3;当然也可以换一种方式写这段代码,不是问题。

你可能感兴趣的:(算法,lintcode)