日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

10.2 动态规划算法套路及空间优化 —— Climbing Stairs Unique Paths

發(fā)布時(shí)間:2024/1/18 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 10.2 动态规划算法套路及空间优化 —— Climbing Stairs Unique Paths 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這一篇文章從最簡(jiǎn)單的動(dòng)態(tài)規(guī)劃題目開始,結(jié)合上一節(jié)動(dòng)態(tài)規(guī)劃三要素,以LeetCode兩道基礎(chǔ)的DP題目闡述DP問題的基本套路解法。


?

70.?Climbing Stairs

You are climbing a stair case. It takes?n?steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Note:?Given?n?will be a positive integer.

?

題目解析:

這是一道最基礎(chǔ)的動(dòng)態(tài)規(guī)劃問題,用于我們初步了解。首先我們來回憶DP三大要素,抽煙喝酒燙頭,不,是最優(yōu)子結(jié)構(gòu),狀態(tài)轉(zhuǎn)移方程和邊界。

  • ?最優(yōu)子結(jié)構(gòu),就是分析問題的關(guān)鍵,構(gòu)建解題框架。之前以斐波那契數(shù)列為例,這次我們以這道題目為例。想知道到達(dá)n層臺(tái)階,有多少種方式,即f(n)是最終想要的答案,抽象為f(i) 即到達(dá)任何一層臺(tái)階的方式;所謂子結(jié)構(gòu),即f(i-1),f(i-2),f(i-3),...,f(2),f(1)。很明顯,f(i)的方案數(shù)目和?f(i-1)等子問題的答案是有關(guān)系的。這就是第一步分析問題我們要做的。
  • 狀態(tài)轉(zhuǎn)移方程。f(i)和子問題具體是什么關(guān)系呢?這一步要定量分析。由于每次只能走一步或兩步,一步之前的臺(tái)階在i-1層,兩步之前在i-2層,那么第i層的方案數(shù)目不就是:f(i) =?f(i-1) +?f(i-2),(還是斐波那契數(shù)列)。這一步定量分析問題和子問題之間的數(shù)量關(guān)系,
  • 邊界。到這兒就很好理解了,可以定義 f(1)=1, f(2)=2.
  • 其實(shí)還有第四步,就是編碼啦,能把你的思路寫出來才行。
  • 下面我們看代碼實(shí)現(xiàn),在dp問題中,對(duì)于f(i)我們一般存為數(shù)組dp.

    class Solution:def climbStairs(self, n: int) -> int:# 特殊情況if n <= 2:return n# dp數(shù)組必備dp = [0] * (n+1)# 邊界dp[1] = 1dp[2] = 2for i in range(3, n+1):# 狀態(tài)轉(zhuǎn)移方程dp[i] = dp[i-1] + dp[i-2]return dp[-1]

    ?

    這個(gè)一維的問題就圖森破了,下面我們看經(jīng)典的二維dp問題。說來說去,二維不一定比一維的就難,一維的數(shù)組也有很多難題。

    62.?Unique Paths

    A robot is located at the top-left corner of a?m?x?n?grid (marked 'Start' in the diagram below).

    The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

    How many possible unique paths are there?

    ?

    題目解析:

    我們仿照上題的思路來解析,看三大要素。f(i,j)表示到達(dá)i行j列的路徑數(shù),f(m,n)即最終結(jié)果。i行j列是從左側(cè)或上邊走過來的,必然有一定的最優(yōu)子結(jié)構(gòu)的形式。那么接下來分析狀態(tài)轉(zhuǎn)移方程。和上一題類似,i行j列的上一步或者在i-1行j列,或者在i行j-1列,只有這兩種情況,且每種情況下只有一條路徑到i,j,因此直接得到f(i,j) = f(i-1,j) + f(i,j-1)。二維問題的邊界也在二維數(shù)組的邊界,下面我們直接看代碼實(shí)現(xiàn):

    class Solution:def uniquePaths(self, m: int, n: int) -> int:# dp數(shù)組dp = [[0] * n for _ in range(m)]# 邊界for i in range(m):dp[i][0] = 1for i in range(n):dp[0][i] = 1for i in range(1, m): for j in range(1, n):# 狀態(tài)轉(zhuǎn)移方程dp[i][j] = dp[i-1][j] + dp[i][j-1]return dp[m-1][n-1] # 或dp[-1][-1]

    再額外解釋一下邊界,沿著第一行或者第一列都是只有一種路徑,所以邊界的初始值都是1,也可以直接把dp數(shù)組初始化為1.


    先充分的消化一下上面兩道問題的dp套路,從三要素理解解題思路,進(jìn)而理解dp的核心思想,最優(yōu)子結(jié)構(gòu)和無后效性。

    根據(jù)無后效性,下面我們看一下dp算法的優(yōu)化思路。

    以climbing stairs為例,基本思路中我們定義了長(zhǎng)度為n的數(shù)組用于存儲(chǔ)i處的最終解,時(shí)間復(fù)雜度O(n);但是從關(guān)系式dp[i] = dp[i-1] + dp[i-2]可以看出,在i處我們只需要i-1和i-2的值,更早的值我們不需要了,這就體現(xiàn)了無后效性,因此我們只需要三個(gè)變量即可解決問題,下面看代碼:

    class Solution:def climbStairs(self, n: int) -> int:if n <= 2:return npre1 = 2pre2 = 1dp = 0for i in range(3, n+1): dp = pre1 + pre2pre2, pre1 = pre1, dpreturn dp

    就是這樣,將空間復(fù)雜度降到了O(1)。我們?cè)倏磚nique paths題目的優(yōu)化。

    對(duì)于第i行第j列,我們看關(guān)系式 f(i,j) = f(i-1,j) + f(i,j-1),在前面的解法中,我們的空間復(fù)雜度是O(m*n),對(duì)于每個(gè)位置來說,我們需要左邊的和上邊的,對(duì)于每一行來說,我們只需要上一行的結(jié)果即可。因此我們可以將空間復(fù)雜度降到O(n),結(jié)合下面代碼來看,我們只定義一個(gè)一維dp數(shù)組,在每行遍歷中,不斷更新dp數(shù)組的值,不斷拋棄上一行的結(jié)果,直到最后一行。

    class Solution:def uniquePaths(self, m: int, n: int) -> int:# 定義一維dp數(shù)組,同時(shí)初始化了第一行的邊界值dp = [1] * nfor i in range(1, m): for j in range(n):# 第一列的邊界if j == 0:dp[j] = 1else:# 相當(dāng)于原狀態(tài)轉(zhuǎn)移方程,不斷更新dp數(shù)組值dp[j] += dp[j-1]return dp[-1]

    ?

    總結(jié)

    以上是生活随笔為你收集整理的10.2 动态规划算法套路及空间优化 —— Climbing Stairs Unique Paths的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。