【Python 算法零基礎 3.遞推】

壓抑與痛苦,那些輾轉反側的夜,終會讓我們更加強大

????????????????????????????????????????????????????????????????????????????????—— 25.5.16

一、遞推的概念

????????遞推 ——?遞推最通俗的理解就是數列,遞推和數列的關系就好比 算法 和 數據結構 的關系,數列有點像數據結構中的線性表(可以是順序表,也可以是鏈表,一般情況下是順序表),而遞推就是一個循環或者迭代的枚舉過程,遞推本質上是數學問題。


二、509. 斐波那契數

斐波那契數?(通常用?F(n)?表示)形成的序列稱為?斐波那契數列?。該數列由?0?和?1?開始,后面的每一項數字都是前面兩項數字的和。也就是:

F(0) = 0,F(1)?= 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1

給定?n?,請計算?F(n)?。

示例 1:

輸入:n = 2
輸出:1
解釋:F(2) = F(1) + F(0) = 1 + 0 = 1

示例 2:

輸入:n = 3
輸出:2
解釋:F(3) = F(2) + F(1) = 1 + 1 = 2

示例 3:

輸入:n = 4
輸出:3
解釋:F(4) = F(3) + F(2) = 2 + 1 = 3

方法一 遞歸

① 終止條件

當?n == 0?時,直接返回?0(對應斐波那契數列的第 0 項)。

當?n == 1?時,直接返回?1(對應斐波那契數列的第 1 項)。

② 遞歸計算

當?n > 1?時,當前項的值為前兩項之和:fib(n) = fib(n-1) + fib(n-2)

遞歸調用自身計算?fib(n-1)?和?fib(n-2),并返回它們的和。

    def fib(self, n: int) -> int:if n == 0:return 0elif n == 1:return 1else:return self.fib(n -2) + self.fib(n - 1)

方法二 迭代

① 初始化結果列表

創建列表?res,初始值為?[0, 1],對應斐波那契數列的前兩項。

② 循環填充中間項

循環范圍i?從 2 到?n-1(不包含?n)。

遞推公式:每次將?res[i-1]?和?res[i-2]?的和添加到?res?中。

返回結果:返回?res[n],即列表的第?n?項(索引為?n)。

    def fib(self, n: int) -> int:res = [0, 1]for i in range(2, n + 1):res.append(res[i - 1] + res[i - 2])return res[n]                            

三、1137. 第 N 個泰波那契數

泰波那契序列?Tn?定義如下:?

T0?= 0, T1?= 1, T2?= 1, 且在 n >= 0?的條件下 Tn+3?= Tn?+ Tn+1?+ Tn+2

給你整數?n,請返回第 n 個泰波那契數?Tn?的值。

示例 1:

輸入:n = 4
輸出:4
解釋:
T_3 = 0 + 1 + 1 = 2
T_4 = 1 + 1 + 2 = 4

示例 2:

輸入:n = 25
輸出:1389537

方法一 遞歸

① 終止條件

當?n == 0?時,直接返回?0(對應斐波那契數列的第 0 項)。

當?n == 1?時,直接返回?1(對應斐波那契數列的第 1 項)。

當?n == 2?時,直接返回?1(對應斐波那契數列的第 2?項)。

② 遞歸計算

當?n > 1?時,當前項的值為前三項之和:fib(n) = fib(n-1) + fib(n-2) + fib(n-3)

遞歸調用自身計算?fib(n-1)?和?fib(n-2)和fib(n-3),并返回它們的和。

class Solution:def tribonacci(self, n: int) -> int:if n == 0:return 0elif n == 1 or n == 2:return 1else:return self.tribonacci(n - 1) + self.tribonacci(n - 2) + self.tribonacci(n - 3)

方法二 迭代

① 初始化結果列表

創建列表?res,初始值為?[0, 1, 1],對應斐波那契數列的前三項。

② 循環填充中間項

循環范圍i?從 3?到?n + 1

遞推公式:每次將?res[i-1]?和?res[i-2] 和 res[i-3]?的和添加到?res?中。

返回結果:返回?res[n],即列表的第?n?項(索引為?n)。

class Solution:def tribonacci(self, n: int) -> int:res = [0, 1, 1]for i in range(3, n + 1):res.append(res[i - 3] + res[i - 2] + res[i - 1])return res[n]

四、斐波那契數列變形 爬樓梯問題

假設你正在爬樓梯。需要?n?階你才能到達樓頂。

每次你可以爬?1?或?2?個臺階。你有多少種不同的方法可以爬到樓頂呢?

示例 1:

輸入:n = 2
輸出:2
解釋:有兩種方法可以爬到樓頂。
1. 1 階 + 1 階
2. 2 階

示例 2:

輸入:n = 3
輸出:3
解釋:有三種方法可以爬到樓頂。
1. 1 階 + 1 階 + 1 階
2. 1 階 + 2 階
3. 2 階 + 1 階

方法一 遞歸?

思路與算法

① 終止條件

當?n == 1?時,只有?1 種爬法(一步)。當?n == 2?時,有?2 種爬法(一步一步或直接兩步)。

② 遞歸分解

當?n > 2?時,最后一步可能是從?n-1?級跨一步到達,或從?n-2?級跨兩步到達。

因此,總爬法數為前兩級的爬法數之和:climbStairs(n) = climbStairs(n-1) + climbStairs(n-2)

class Solution:def climbStairs(self, n: int) -> int:if n == 1:return 1elif n == 2:return 2else:return self.climbStairs(n - 1) + self.climbStairs(n - 2)

方法二 迭代

思路與算法

① 初始化結果列表

創建列表?res,初始值為?[1, 1],分別對應?n=0?和?n=1?的爬法數。注意:此處?res[0]=1?是為了后續計算方便,實際題目中?n ≥ 1,因此?res[0]?不會被直接使用。

② 循環填充結果列表

循環范圍i?從 2 到?n(包含?n)。

遞推公式:對于每個?i,計算?res[i] = res[i-1] + res[i-2],即前兩級的爬法數之和。

返回結果:返回?res[n],即第?n?級樓梯的爬法數。

class Solution:def climbStairs(self, n: int) -> int:res = [1, 1]for i in range(2, n + 1):res.append(res[i - 1] + res[i - 2])return res[n]

五、二維遞推問題

? ? ? ? 像斐波那契數列這種問題,是一個一維數組來解決的,有時候一維數組解決不了的問題我們應該升高一個維度看

? ? ? ? 長度為 n(1 ≤ n < 40)的只由“A"、"C"、"M"三種字符組成的字符串,可以只有其中一種或兩種字符,但絕對不能有其他字符,且禁止出現 M 相鄰的情況,問這樣的串有多少種???? ?

思路與算法

① 邊界條件處理

當?n = 0?時,直接返回 0(空字符串)。

② 狀態定義

dp[i][0]長度為?i?且最后一個字符是?M?的字符串數目。

dp[i][1]長度為?i?且最后一個字符不是?M(即?A?或?C)的字符串數目。

Ⅰ、初始化

當?i = 1?時:dp[1][0] = 1(字符串為?M)。dp[1][1] = 2(字符串為?A?或?C)。

Ⅱ、狀態轉移(循環?i?從 2 到?n

計算?dp[i][0](末尾為?M):前一個字符不能是?M(否則相鄰),因此只能從?dp[i-1][1]?轉移而來。遞推式:dp[i][0] = dp[i-1][1]

計算?dp[i][1](末尾為非?M):前一個字符可以是?M?或非?M(即?dp[i-1][0] + dp[i-1][1])。當前字符有 2 種選擇(A?或?C),因此總數乘以 2。遞推式:dp[i][1] = (dp[i-1][0] + dp[i-1][1]) * 2

Ⅲ、結果計算

最終結果為長度為?n?的所有合法字符串數目,即?dp[n][0] + dp[n][1]

def count_valid_strings(n: int) -> int:if n == 0:return 0# dp[i][0]: 長度為i且最后一個字符是M的字符串數目# dp[i][1]: 長度為i且最后一個字符不是M的字符串數目dp = [[0, 0] for _ in range(n + 1)]dp[1][0] = 1  # Mdp[1][1] = 2  # A, Cfor i in range(2, n + 1):dp[i][0] = dp[i-1][1]  # 前一個字符不能是Mdp[i][1] = (dp[i-1][0] + dp[i-1][1]) * 2  # 前一個字符任意,當前選A/Creturn dp[n][0] + dp[n][1]

六、119. 楊輝三角 II

給定一個非負索引?rowIndex,返回「楊輝三角」的第?rowIndex?行。

在「楊輝三角」中,每個數是它左上方和右上方的數的和。

示例 1:

輸入: rowIndex = 3
輸出: [1,3,3,1]

示例 2:

輸入: rowIndex = 0
輸出: [1]

示例 3:

輸入: rowIndex = 1
輸出: [1,1]

提示:

  • 0 <= rowIndex <= 33

進階:

你可以優化你的算法到?O(rowIndex)?空間復雜度嗎?

思路與算法

① 初始化結果列表

創建空列表?resRows,用于存儲楊輝三角的每一行。

② 逐行生成楊輝三角

Ⅰ、外層循環i?從 0 到?rowIndex

對于每一行?i,創建空列表?resCols?用于存儲當前行的元素。

Ⅱ、內層循環j?從 0 到?i):

邊界條件:當?j?是當前行的第一個或最后一個元素時(即?j == 0?或?j == i),直接添加?1

遞推關系:否則,當前元素的值為上一行的?j-1?和?j?位置元素之和(即?resRows[i-1][j-1] + resRows[i-1][j])。將當前行?resCols?添加到?resRows?中。

返回指定行:循環結束后,返回?resRows?中的第?rowIndex?行。

class Solution:def getRow(self, rowIndex: int) -> List[int]:resRows = []for i in range(rowIndex + 1):resCols = []for j in range(i + 1):if j == 0 or j == i:resCols.append(1)# f[i][j] = f[i - 1][j - 1] + f[i - 1][j]else:resCols.append(resRows[i - 1][j] + resRows[i - 1][j - 1])resRows.append(resCols)return resRows[rowIndex]

七、119. 楊輝三角 II?空間優化

給定一個非負索引?rowIndex,返回「楊輝三角」的第?rowIndex?行。

在「楊輝三角」中,每個數是它左上方和右上方的數的和。

示例 1:

輸入: rowIndex = 3
輸出: [1,3,3,1]

示例 2:

輸入: rowIndex = 0
輸出: [1]

示例 3:

輸入: rowIndex = 1
輸出: [1,1]

提示:

  • 0 <= rowIndex <= 33

進階:

你可以優化你的算法到?O(rowIndex)?空間復雜度嗎?

算法與思路

① 初始化二維數組?f

創建一個 2 行、rowIndex+1?列的二維數組?f,用于存儲中間結果。初始化?pre = 0?和?now = 1,分別表示當前行和前一行的索引。

② 設置初始條件

f[pre][0] = 1,對應楊輝三角的第一行?[1]

③ 逐行生成楊輝三角

Ⅰ、外層循環i?從 0 到?rowIndex

遍歷每一行,生成當前行的元素。

Ⅱ、內層循環j?從 0 到?i

邊界條件:當?j?是當前行的第一個或最后一個元素時,設為?1

遞推關系:否則,當前元素的值為前一行的?j?和?j-1?位置元素之和(即?f[pre][j] + f[pre][j-1])。更新?pre?和?now?的值,交換當前行和前一行的角色。

返回結果:循環結束后,pre?指向的行即為所求的第?rowIndex?行,返回?f[pre]

class Solution:def getRow(self, rowIndex: int) -> List[int]:f = []for i in range(0, 2):l = []for j in range(rowIndex + 1):l.append(0)f.append(l)pre = 0now = 1f[pre][0] = 1for i in range(0, rowIndex + 1):l = []for j in range(i + 1):if j == 0 or j == i:f[now][j] = 1else:f[now][j] = f[pre][j] + f[pre][j - 1]pre, now = now, prereturn f[pre]

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/80425.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/80425.shtml
英文地址,請注明出處:http://en.pswp.cn/web/80425.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

淘寶扭蛋機系統開發前景分析:解鎖電商娛樂化新藍海

在電商行業競爭日益白熱化的當下&#xff0c;如何通過創新玩法提升用戶粘性、激活消費潛力&#xff0c;成為平臺突破增長瓶頸的關鍵。淘寶扭蛋機系統作為“電商娛樂”的跨界融合產物&#xff0c;正憑借其趣味性、隨機性和社交屬性&#xff0c;成為撬動年輕消費市場的潛力工具。…

NHANES指標推薦:UHR

文章題目&#xff1a;Elevated log uric acid-to-high-density lipoprotein cholesterol ratio (UHR) as a predictor of increased female infertility risk: insights from the NHANES 2013-2020 DOI&#xff1a;10.1186/s12944-025-02521-w 中文標題&#xff1a;對數尿酸與高…

【c庫主要功能】

1 stdio.h 功能&#xff1a;處理文件和標準輸入/輸出流的各種函數和類型 包含變量&#xff1a; size_t&#xff1a;無符號整形&#xff0c;sizeof關鍵字的結果FILE&#xff1a;文件流類型&#xff0c;適合存儲文件流信息的對象類型 庫宏&#xff1a; stderr、stdin、stdout&a…

npm 報錯 gyp verb `which` failed Error: not found: python2 解決方案

一、背景 npm 安裝依賴報如下錯&#xff1a; gyp verb check python checking for Python executable "python2" in the PATH gyp verb which failed Error: not found: python2 一眼看過去都覺得是Python環境問題&#xff0c;其實并不是你python環境問題&#xf…

常見的請求頭(Request Header)參數

1. Accept 作用&#xff1a;告知服務器客戶端支持的響應數據格式&#xff08;如 JSON、XML、HTML&#xff09;。示例&#xff1a;Accept: application/json&#xff08;優先接收 JSON 格式數據&#xff09;。 2. Content-Type 作用&#xff1a;說明請求體的數據格式&#xff08…

計算機網絡:移動通信蜂窩網絡指的是什么?

無線基站的蜂窩網絡(Cellular Network)是現代移動通信系統的核心架構,其核心思想是通過蜂窩狀小區劃分和頻率復用,實現廣域覆蓋、高效頻譜利用和動態資源管理。以下從設計原理、網絡架構、關鍵技術及實際挑戰等方面深入解析蜂窩網絡。 一、蜂窩網絡的設計原理 1. 蜂窩結構…

【AI論文】對抗性后期訓練快速文本到音頻生成

摘要&#xff1a;文本到音頻系統雖然性能不斷提高&#xff0c;但在推理時速度很慢&#xff0c;因此對于許多創意應用來說&#xff0c;它們的延遲是不切實際的。 我們提出了對抗相對對比&#xff08;ARC&#xff09;后訓練&#xff0c;這是第一個不基于蒸餾的擴散/流模型的對抗加…

Word文檔圖片和圖表自動添加序號

0 Preface/Foreword Word文檔是辦公常用的文檔&#xff0c;里面經常會插入圖片或者表格&#xff0c;當表格和圖片數量過多時&#xff0c;如果有些圖片需要刪除或者添加&#xff0c;那么大概率需要修改大量圖片的序號或者引用記錄&#xff0c;如果通過手工一個一個修改&#xf…

軟件架構設計--期末復習

質量屬性 參考視頻&#xff1a;【13.5質量屬性-架構評估】 在軟件架構中&#xff0c;質量屬性是衡量系統設計優劣的關鍵指標&#xff0c;通常分為運行時屬性和非運行時屬性。以下是一些常見的質量屬性&#xff1a; 一、軟件架構中的質量屬性 運行時屬性&#xff1a; 性能&am…

多指標組合策略思路

一種基于多種技術指標和日歷因素的綜合交易策略&#xff0c;旨在通過復雜的條件判斷來預測市場的短期走勢&#xff0c;并據此進行買賣操作。 策略概述 該策略的核心思想是通過結合多個技術指標和日歷因素來判斷市場的短期趨勢&#xff0c;并在合適的時機進行買入或賣出操作。 具…

STM32 HAL驅動程序 內部Flash

hal_flash.c #include "hal_flash.h"volatile uint32_t flashWriteOffset SYS_APP_BAK_SAVE_ADDR_BASE; volatile uint32_t flashReadOffset SYS_APP_BAK_SAVE_ADDR_BASE;/* MCU OTA */ /*擦除指定的Flash頁*/ void flash_erase_page(uint8_t flashPage , uint32_…

電子電路:什么是電流離散性特征?

關于電荷的量子化,即電荷的最小單位是電子的電荷量e。在宏觀電路中,由于電子數量極大,電流看起來是連續的。但在微觀層面,比如納米器件或單電子晶體管中,單個電子的移動就會引起可觀測的離散電流。 還要提到散粒噪聲,這是電流離散性的表現之一。當電流非常小時,例如在二…

AI agent與lang chain的學習筆記 (1)

文章目錄 智能體的4大要素一些上手的例子與思考。創建簡單的AI agent.從本地讀取文件&#xff0c;然后讓AI智能體總結。 也可以自己定義一些工具 來完成一些特定的任務。我們可以使用智能體總結一個視頻。用戶可以隨意問關于視頻的問題。 智能體的4大要素 AI 智能體有以下幾個…

react+html2canvas+jspdf將頁面導出pdf

主要使用html2canvasjspdf 1.將前端頁面導出為pdf 2.處理導出后圖表的截斷問題 export default function AIReport() {const handleExport async () > {try {// 需要導出的內容idconst element document.querySelector(#AI-REPORT-CONTAINER);if (!element) {message.err…

FFmpeg:多媒體處理的終極利器

FFmpeg詳細介紹 1. 定義與基本概述 FFmpeg是一套開源的跨平臺多媒體處理工具集,最初由法國程序員Fabrice Bellard于2000年開發,其名稱源自“Fast Forward MPEG”,體現了其高效處理MPEG格式的能力。它不僅是命令行工具,還包含多個庫和開發套件,支持視頻轉碼、剪輯、合并、…

【應用開發十】pwm

1 應用層操作PWM 與LED設備一樣&#xff0c;操作PWD也是通過sysfs方式 1&#xff09; 所在目錄&#xff1a;/sys/class/pwm&#xff0c;該目錄下的文件為pwmchipX&#xff0c;為PWM控器&#xff0c;I.MX6ULL有八個pwm控制器 1.1 pwm 控制器 PWM控制器里內容&#xff08;即pw…

LeetCode算 法 實 戰 - - - 雙 指 針 與 移 除 元 素、快 慢 指 針 與 刪 除 有 序 數 組 中 的 重 復 項

LeetCode算 法 實 戰 - - - 雙 指 針 與 移 除 元 素、快 慢 指 針 與 刪 除 有 序 數 組 中 的 重 復 項 第 一 題 - - - 移 除 元 素方 法 一 - - - 雙 重 循 環方 法 二 - - - 雙 指 針方 法 三 - - - 相 向 雙 指 針&#xff08;面 對 面 移 動&#xff09; 第 二 題 - - -…

設計模式系列(03):設計原則(二):DIP、ISP、LoD

本文為設計模式系列第3篇,聚焦依賴倒置、接口隔離、迪米特法則三大設計原則,系統梳理定義、實際業務場景、優缺點、最佳實踐與常見誤區,適合系統學習與團隊協作。 目錄 1. 引言2. 依賴倒置原則(DIP)3. 接口隔離原則(ISP)4. 迪米特法則(LoD)5. 常見誤區與反例6. 最佳實…

計算機圖形學中MVP變換的理論推導

計算機圖形學中MVP變換的理論推導 課程地址&#xff1a;Computing the Pixel Coordinates of a 3D Point 知識鋪墊&#xff1a;矩陣的真實內涵 矩陣的每一列/行&#xff08;左乘和右乘的區別&#xff09;代表了新坐標系的基向量在原基向量構成的坐標系中的坐標&#xff0c;這…

先說愛的人為什么先離開

2025年5月19日&#xff0c;15~23℃&#xff0c;賊好的一天&#xff0c;無事發生 待辦&#xff1a; 2024年稅務申報 《高等數學2》取消考試資格學生名單 《物理[2]》取消考試資格名單 5月24日、25日監考報名 《高等數學2》備課 《物理[2]》備課 職稱申報材料 教學技能大賽PPT 遇…