10.2 动态规划算法套路及空间优化 —— Climbing Stairs Unique Paths
這一篇文章從最簡(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)移方程和邊界。
下面我們看代碼實(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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .net中mvc问卷制作
- 下一篇: 如何选购电脑主板?