《極客時間--算法面試》--動態規劃

題目:70、爬樓梯python

思路:數組

  1、採用回溯法,遞歸+記憶化app

  2、採用動態規劃,時間複雜度爲O(n),採用遞推的方式編碼

    要找到DP的狀態和DP方程。spa

  

 

代碼(動態規劃):code

class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        '''   
        方式一:傳統的方式
        if n==0 or n==1 or n==2:                #邊界值斷定
            return n                            
        men = [1,2]                             #遞推初始值
        for i in range(2,n):                    #從第二個開始到最後
            men.append(men[i-1]+men[i-2])       #將前面兩個值相加最爲後一個值
        return men[n-1]                         #返回最後的一個結果
        '''
        '''方式二:python的編碼方式較爲簡潔,直接賦值的'''
        x,y = 1,1
        for _ in range(1,n):
            x,y = y,x+y
        return y

題目:120、三角形最小路徑和blog

思路:遞歸

  1、回溯leetcode

  2、動態規劃get

    從底層倒推,明確狀態轉移方程和初始狀態。

    初始狀態是最後一層,轉移方程是相鄰節點的最小值和當前值相加做爲下一個狀態的值。

代碼:

class Solution(object):
    def minimumTotal(self, triangle):
        """
        :type triangle: List[List[int]]
        :rtype: int
        """
        if not triangle:                                        #邊界判斷
            return 0
        res = triangle[-1]                                      #初始狀態爲最後層
        for i in range(len(triangle)-2,-1,-1):                  #從底層到上層進行遍歷
            for j in range(len(triangle[i])):                   #每一層從左往右遍歷
                res[j] = min(res[j],res[j+1])+triangle[i][j]    #當前節點的相鄰節點之間最小值加上當前節點
        return res[0]                                           #最終的結果值就是最頂層的數

  須要一個一維的數組進行狀態壓縮。

題目:152乘積最大子序列

思路:

  1、採用遞歸的思路,暴力解決

    採用遞歸的思路但採用循環的方式編碼。對每個值進行乘積,將當前最大值進行保存起來,若是與當前的乘積小於前面值就賦值爲1.最終返回最大的那個值便可。

  2、採用動態規劃,採用遞推的方式

    1、狀態的定義,一個二維方程,存放正向最大值和負向最小值,兩個負數相乘會變正數。

    2、狀態方程,最大和最小的值,是比較當前值和當前值和前面乘積的乘積。

代碼:

class Solution(object):
    def maxProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if nums is None: return 0                                       #邊界判斷
        dp = [[0 for _ in range(2)]for _ in range(2)]                   #定義狀態,二維數組,存放正向最大和負向最小
        dp[0][1],dp[0][0],res = nums[0],nums[0],nums[0]                 #狀態初始值,從第一個值開始
        for i in range(1,len(nums)):                                    #從第二個值開始遍歷
            x,y = i%2,(i-1)%2                                           #0,1週期性調控
            dp[x][0] = max(dp[y][0]*nums[i],dp[y][1]*nums[i],nums[i])   #正向最大值
            dp[x][1] = min(dp[y][0]*nums[i],dp[y][1]*nums[i],nums[i])   #負向最小值
            res = max(res,dp[x][0])                                     #每次都保存最大的值,最終返回
        return res

  如下題目買賣股票的最佳時機系列題目均採用動態規劃思路去作,明確動態規劃的兩個基本點:定義狀態、狀態轉移方程和最終的目標結果值。如下思路是通用的泛華思路,定義了三個狀態,根據具體的需求再進行細微修改。

  明確狀態含義:

    dp[i][j][k]:第i天的最大收益第k次交易的最大收益

    i:第i天【0,n-1】

    j:手上是否持有【0、1】表明手上只能持有一股,能夠多股

    k:第k次交易【0,k】

    若是是冷凍時期能夠在加狀態,好比是否冷凍期,取值範圍是0、1等。

  初始狀態:

    

  狀態轉義方程:

    通俗講:在考慮上次交易的前提下,根據手上是否有股票分別做出行動,因爲只有兩種狀況,便是否持有,後期能夠改成

      手上有股票:保持當前的股票和賣掉手上的股票的最大值

      手上沒有股票:保持手上沒有股票和買入當前餓股票的最大值

  三個循環進行遍歷,第一個循環遍歷第幾天,第二個循環遍歷第幾回買賣。第三個循環根據手上的股票個數進行操做。針對第一題只有一個股票,後面多個股票,細微修改。

  最終的結果值是最後一天股票操做後在這k次中最大的一個利潤值。

股票買賣題目:121股票買賣的最佳時機I

只能進行一次交易

思路:

  

代碼:

股票買賣題目:122股票買賣的最佳時機II

無數次交易

思路:

代碼:

股票買賣題目:123股票買賣的最佳時機III

只能兩次交易

思路:

代碼:

股票買賣題目:188股票買賣的最佳時機IV

K次交易

思路:

代碼:

股票買賣題目:309最佳股票買賣的最佳時機含冷凍期

兩次交易中間會有限制

思路:

代碼:

股票買賣題目:714股票買賣的最佳時機含手續費

思路:

代碼:

相關文章
相關標籤/搜索