面試算法高頻08-動態規劃-02

動態規劃練習題

題目描述

給定兩個字符串 text1text2,要求返回這兩個字符串的最長公共子序列。例如對于字符串 “ABAZDC” 和 “BACBAD”,需找出它們最長的公共子序列。子序列是指在不改變其余字符相對位置的情況下,從原始字符串中刪除某些字符(也可以不刪除)后形成的新字符串。

最優解(Python)
def longestCommonSubsequence(text1, text2):m, n = len(text1), len(text2)dp = [[0] * (n + 1) for _ in range(m + 1)]for i in range(1, m + 1):for j in range(1, n + 1):if text1[i - 1] == text2[j - 1]:dp[i][j] = dp[i - 1][j - 1] + 1else:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])return dp[m][n]
解析
  1. 動態規劃思路:本題采用動態規劃方法,核心是通過分析子問題的解來構建最終問題的解。
  2. 狀態定義:定義二維數組 dp[i][j] 表示 text1 的前 i 個字符和 text2 的前 j 個字符的最長公共子序列長度。
  3. 狀態轉移方程
    • text1[i - 1] == text2[j - 1] 時,說明當前字符相等,此時 dp[i][j] 等于 dp[i - 1][j - 1] + 1 ,即在前 i - 1 和前 j - 1 個字符最長公共子序列基礎上長度加1。
    • text1[i - 1] != text2[j - 1] 時,dp[i][j]dp[i - 1][j]dp[i][j - 1] 中的較大值,因為此時最長公共子序列要么是 text1i - 1 個字符與 text2j 個字符的最長公共子序列,要么是 text1i 個字符與 text2j - 1 個字符的最長公共子序列。
  4. 邊界條件dp[0][j] = 0 表示 text1 為空字符串時,最長公共子序列長度為0;dp[i][0] = 0 表示 text2 為空字符串時,最長公共子序列長度為0 。
  5. 時間復雜度:由于使用了兩層嵌套循環遍歷兩個字符串,時間復雜度為 O ( m × n ) O(m \times n) O(m×n),其中 m m m n n n 分別是 text1text2 的長度。
  6. 空間復雜度:使用了一個二維數組 dp 存儲中間結果,空間復雜度為 O ( m × n ) O(m \times n) O(m×n) ,不過可以通過滾動數組優化為 O ( m i n ( m , n ) ) O(min(m, n)) O(min(m,n))

題目描述

題目鏈接為https://leetcode-cn.com/problems/climbing-stairs/description/ ,假設你正在爬樓梯,需要 n 階才能到達樓頂。每次你可以爬 12 個臺階,要求計算有多少種不同的方法可以爬到樓頂 。其中,n 是一個正整數,且滿足 1 <= n <= 45 。例如:

  • 當輸入 n = 2 時,輸出為 2,因為有兩種方法可以爬到樓頂,分別是 “1 階 + 1 階” 和 “2 階” 。
  • 當輸入 n = 3 時,輸出為 3,因為有三種方法可以爬到樓頂,分別是 “1 階 + 1 階 + 1 階” 、“1 階 + 2 階” 、“2 階 + 1 階” 。
最優解(Python)
def climbStairs(n):if n <= 2:return na, b = 1, 2for _ in range(2, n):a, b = b, a + breturn b
解析
  1. 動態規劃思路:本題可采用動態規劃的方法求解。動態規劃的核心是將原問題分解為多個子問題,通過求解子問題并保存結果來避免重復計算,最終得到原問題的解。
  2. 狀態定義:定義 f(n) 表示爬到第 n 階樓梯的不同方法數。
  3. 狀態轉移方程:因為每次可以爬 1 階或 2 階,所以爬到第 n 階的方法數等于爬到第 n - 1 階的方法數加上爬到第 n - 2 階的方法數,即 f(n) = f(n - 1) + f(n - 2) 。這是一個類似斐波那契數列的遞推關系。
  4. 邊界條件:當 n = 1 時,只有一種方法(爬 1 階),即 f(1) = 1 ;當 n = 2 時,有兩種方法(兩次爬 1 階或一次爬 2 階) ,即 f(2) = 2
  5. 代碼實現細節:代碼中使用了兩個變量 ab 分別表示 f(n - 2)f(n - 1) ,通過不斷更新這兩個變量來計算 f(n) 。循環從 n = 2 開始,每次迭代更新 ab 的值,最終 b 存儲的就是爬到第 n 階的方法數。
  6. 復雜度分析
    • 時間復雜度:代碼中只進行了一次循環,循環次數為 n - 2 次,每次循環的操作都是常數時間的,所以時間復雜度為 O ( n ) O(n) O(n)
    • 空間復雜度:只使用了常數個額外變量(ab ),所以空間復雜度為 O ( 1 ) O(1) O(1) 。 這種空間復雜度為常數的實現方式是對動態規劃空間優化后的結果,相較于使用數組存儲所有子問題結果(空間復雜度為 O ( n ) O(n) O(n) )更為高效。

題目描述

題目鏈接為https://leetcode-cn.com/problems/triangle/description/ ,給定一個三角形 triangle ,它是一個二維列表,其中 triangle[i] 表示三角形第 i 行的數字列表。要求找到從三角形頂部到底部的最小路徑和。在每一步只能移動到下一行中相鄰的節點上。例如,對于三角形 [[2],[3,4],[6,5,7],[4,1,8,3]] ,從頂部到底部的最小路徑和是 11(路徑為 2→3→5→1 )。

最優解(Python)
def minimumTotal(triangle):n = len(triangle)# 從倒數第二行開始向上遍歷for i in range(n - 2, -1, -1):for j in range(len(triangle[i])):# 狀態轉移:選擇下方相鄰兩個數中較小的,加上當前數triangle[i][j] += min(triangle[i + 1][j], triangle[i + 1][j + 1])return triangle[0][0]
解析
  1. 動態規劃思路:采用動態規劃來解決此問題。動態規劃的關鍵在于將問題分解為多個子問題,并利用子問題的解來構建最終問題的解。
  2. 狀態定義:把 triangle[i][j] 看作狀態,表示從三角形第 i 行第 j 列這個位置到底部的最小路徑和。
  3. 狀態轉移方程:對于第 i 行第 j 列的元素,它下一步可以移動到下一行的第 j 列或者第 j + 1 列。所以 triangle[i][j] 的最小路徑和等于當前位置的值加上下一行相鄰兩個位置中較小的那個位置的最小路徑和,即 triangle[i][j] += min(triangle[i + 1][j], triangle[i + 1][j + 1])
  4. 遍歷順序:從三角形的倒數第二行開始向上遍歷,因為最底層的元素到底部的最小路徑和就是其自身的值,以此為基礎向上遞推。
  5. 邊界條件:最底層的元素不需要進行額外計算,其自身值就是從它到底部的最小路徑和(因為已經是最底層了)。
  6. 復雜度分析
    • 時間復雜度:使用了兩層嵌套循環,外層循環遍歷行數,內層循環遍歷每行的元素,總的時間復雜度為 O ( n 2 ) O(n^2) O(n2) ,其中 n n n 是三角形的行數。
    • 空間復雜度:直接在原三角形數組上進行操作,沒有使用額外的與問題規模相關的空間,所以空間復雜度為 O ( 1 ) O(1) O(1) 。 這種在原數據結構上直接修改來保存中間結果的方式,有效避免了額外的空間開銷。

題目描述

鏈接:https://leetcode-cn.com/problems/maximum-subarray/ 。

給定一個整數數組 nums ,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。例如,輸入 nums = [-2,1,-3,4,-1,2,1,-5,4] ,輸出為 6 ,因為連續子數組 [4,-1,2,1] 的和最大,為 6

最優解(Python)
def maxSubArray(nums):n = len(nums)if n == 0:return 0dp = [0] * ndp[0] = nums[0]max_sum = dp[0]for i in range(1, n):dp[i] = max(nums[i], dp[i - 1] + nums[i])max_sum = max(max_sum, dp[i])return max_sum
解析
  1. 動態規劃思路:本題運用動態規劃方法。動態規劃的核心是將復雜問題分解為多個相互關聯的子問題,通過求解子問題并保存結果,避免重復計算,從而高效地解決原問題。
  2. 狀態定義:定義 dp[i] 表示以 nums[i] 結尾的連續子數組的最大和 。
  3. 狀態轉移方程:對于 dp[i] ,它有兩種情況。一種是只取 nums[i] 這一個元素作為子數組,另一種是將 nums[i] 加入到以 nums[i - 1] 結尾的連續子數組中。所以狀態轉移方程為 dp[i] = max(nums[i], dp[i - 1] + nums[i])
  4. 邊界條件:當 i = 0 時,dp[0] = nums[0] ,因為此時以 nums[0] 結尾的連續子數組就是它本身。
  5. 求解過程:在循環中,每計算出一個 dp[i] ,就更新 max_summax_sum 記錄的是到當前位置為止,所有以不同元素結尾的連續子數組中的最大和。
  6. 復雜度分析
    • 時間復雜度:代碼中只有一層循環,循環次數為數組的長度 n ,每次循環內的操作都是常數時間的,所以時間復雜度為 O ( n ) O(n) O(n)
    • 空間復雜度:使用了一個長度為 n 的數組 dp 來保存中間結果,所以空間復雜度為 O ( n ) O(n) O(n) 。不過,還可以進一步優化,將空間復雜度降為 O ( 1 ) O(1) O(1) ,即不使用 dp 數組,而是用一個變量來記錄以當前元素結尾的最大子數組和。優化后的代碼如下:
def maxSubArray(nums):n = len(nums)if n == 0:return 0cur_sum = nums[0]max_sum = nums[0]for i in range(1, n):cur_sum = max(nums[i], cur_sum + nums[i])max_sum = max(max_sum, cur_sum)return max_sum

此時,只使用了幾個額外的變量,空間復雜度為 O ( 1 ) O(1) O(1)

題目描述(另一題,鏈接:https://leetcode-cn.com/problems/maximum-product-subarray/description/ )

給定一個整數數組 nums ,找出一個乘積最大的連續子數組。子數組最少包含一個元素。例如,輸入 nums = [2,3,-2,4] ,輸出為 6 ,因為子數組 [2,3] 有最大乘積 6

最優解(Python)
def maxProduct(nums):n = len(nums)if n == 0:return 0max_ending_here = min_ending_here = res = nums[0]for i in range(1, n):# 暫存當前的最大值,用于計算新的最小值temp_max = max_ending_heremax_ending_here = max(nums[i], max_ending_here * nums[i], min_ending_here * nums[i])min_ending_here = min(nums[i], temp_max * nums[i], min_ending_here * nums[i])res = max(res, max_ending_here)return res
解析
  1. 動態規劃思路:同樣采用動態規劃策略。由于數組中存在負數,負數與負數相乘可能得到更大的乘積,所以不能簡單地用與最大子數組和類似的方法。需要同時記錄以當前元素結尾的最大乘積子數組和最小乘積子數組。
  2. 狀態定義:定義 max_ending_here 表示以當前元素 nums[i] 結尾的最大乘積子數組的乘積,min_ending_here 表示以當前元素 nums[i] 結尾的最小乘積子數組的乘積 。
  3. 狀態轉移方程
    • 對于 max_ending_here ,它的取值可能是當前元素 nums[i] ,也可能是當前元素與之前的 max_ending_here 相乘,還可能是當前元素與之前的 min_ending_here 相乘(因為負負得正,可能得到更大的值),即 max_ending_here = max(nums[i], max_ending_here * nums[i], min_ending_here * nums[i])
    • 對于 min_ending_here ,它的取值可能是當前元素 nums[i] ,也可能是當前元素與之前的 max_ending_here 相乘(得到較小的值),還可能是當前元素與之前的 min_ending_here 相乘,即 min_ending_here = min(nums[i], temp_max * nums[i], min_ending_here * nums[i]) 。這里的 temp_max 是暫存的上一輪的 max_ending_here ,用于計算新的 min_ending_here
  4. 邊界條件:當 i = 0 時,max_ending_here = min_ending_here = nums[0]
  5. 求解過程:在循環中,每次更新 max_ending_heremin_ending_here 后,都用 res 記錄到當前位置為止的最大乘積,最后返回 res
  6. 復雜度分析
    • 時間復雜度:只有一層循環,循環次數為數組長度 n ,每次循環內操作是常數時間,所以時間復雜度為 O ( n ) O(n) O(n)
    • 空間復雜度:只使用了幾個額外變量,空間復雜度為 O ( 1 ) O(1) O(1)

題目描述

題目鏈接為https://leetcode-cn.com/problems/coin-change/description/ 。給定不同面額的硬幣 coins 列表和一個總金額 amount ,編寫一個函數來計算可以湊成總金額所需的最少的硬幣個數 。如果沒有任何一種硬幣組合能組成總金額,返回 -1 。假設每種硬幣的數量是無限的。例如:

  • 輸入 coins = [1, 2, 5]amount = 11 ,輸出為 3 ,因為 11 = 5 + 5 + 1 ,最少需要 3 枚硬幣。
  • 輸入 coins = [2]amount = 3 ,輸出為 -1 ,因為無法用面額為 2 的硬幣湊出金額 3
最優解(Python)
def coinChange(coins, amount):dp = [amount + 1] * (amount + 1)dp[0] = 0for i in range(1, amount + 1):for coin in coins:if coin <= i:dp[i] = min(dp[i], dp[i - coin] + 1)return dp[amount] if dp[amount] != amount + 1 else -1
解析
  1. 動態規劃思路:本題使用動態規劃來解決。動態規劃的核心在于將問題分解為多個子問題,通過求解子問題并保存結果,避免重復計算,最終得到原問題的解。
  2. 狀態定義:定義 dp[i] 表示湊成金額 i 所需的最少硬幣個數。
  3. 狀態轉移方程:對于金額 i ,遍歷所有硬幣面額 coin ,如果 coin <= i ,那么 dp[i] 可以由 dp[i - coin] + 1 得到(dp[i - coin] 是湊成金額 i - coin 所需的最少硬幣個數,加上一枚面額為 coin 的硬幣就可以湊成金額 i ),并且取 dp[i]dp[i - coin] + 1 中的較小值,即 dp[i] = min(dp[i], dp[i - coin] + 1)
  4. 邊界條件dp[0] = 0 ,表示湊成金額 0 不需要任何硬幣。初始化 dp 數組其他元素為 amount + 1 ,這是一個不可能達到的較大值,用于后續比較更新。
  5. 求解過程:通過兩層循環,外層循環遍歷從 1amount 的所有金額,內層循環遍歷所有硬幣面額,不斷更新 dp 數組。最后,如果 dp[amount] 仍然是初始的 amount + 1 ,說明無法湊出該金額,返回 -1 ;否則返回 dp[amount]
  6. 復雜度分析
    • 時間復雜度:有兩層循環,外層循環次數為 amount 次,內層循環次數為硬幣種類數(假設為 m ),所以時間復雜度為 O ( m × a m o u n t ) O(m \times amount) O(m×amount)
    • 空間復雜度:使用了一個長度為 amount + 1 的數組 dp 來保存中間結果,所以空間復雜度為 O ( a m o u n t ) O(amount) O(amount)

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

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

相關文章

【人工智能學習-01-01】20250419《數字圖像處理》復習材料的word合并PDF,添加頁碼

前情提要 20250419今天是上師大繼續教育人工智能專升本第一學期的第一次線下課。 三位老師把視頻課的內容提煉重點再面授。&#xff08;我先看了一遍視頻&#xff0c;但是算法和圖像都看不懂&#xff0c;后來就直接掛分刷滿時間&#xff0c;不看了&#xff09; 今天是面對面授…

AI寫代碼工具分享:Cursor 高效使用攻略與實戰秘籍

寫在前面 在軟件開發領域,效率和生產力是永恒的追求。集成開發環境(IDE)作為開發者的核心工具,其能力直接影響著開發速度和質量。近年來,人工智能(AI)的浪潮席卷了各個行業,編程領域也不例外。Cursor IDE 正是這股浪潮中的佼佼者,它以 AI-First 的理念,在廣受歡迎的…

守護進程編程

守護進程編程 守護進程的含義 定義 守護進程&#xff08;Daemon Process&#xff09;是在后臺運行的進程&#xff0c;它獨立于控制終端并且周期性地執行某種任務或等待處理某些發生的事件。守護進程是一種很有用的進程&#xff0c;它在系統后臺運行&#xff0c;為系統或其他…

在復雜性的迷宮里尋找路標 —— 讀《人月神話》有感

初讀《人月神話》時&#xff0c;正值參與的第一個大型項目陷入泥潭&#xff1a;需求像不斷膨脹的氣球&#xff0c;團隊規模從 10 人擴充到 30 人&#xff0c;進度卻像被灌了鉛的鐘表&#xff0c;指針越來越沉重。布魯克斯在書中寫下的 "向進度落后的項目增加人力&#xff…

SpringCloud Alibaba微服務工程搭建

前言 在講微服務工程的搭建之前&#xff0c;我們先分析下為什么要使用微服務呢&#xff1f; 1、單體應用的痛點 維護困難&#xff1a;代碼臃腫&#xff0c;牽一發而動全身。擴展性差&#xff1a;無法按需擴展特定功能&#xff0c;只能整體擴容。技術棧僵化&#xff1a;難以引…

flutter json解析增強

依賴:xxf_json 反序列化兼容特征一覽表 類型\是否兼容 int double num string bool int yes yes yes yes yes double yes yes yes yes yes num yes yes yes yes yes string yes yes yes yes yes bool yes yes yes yes yes 專業詞語 .g…

Neo4j初解

Neo4j 是目前應用非常廣泛的一款高性能的 NoSQL 圖數據庫&#xff0c;其設計和實現專門用于存儲、查詢和遍歷由節點&#xff08;實體&#xff09;、關系&#xff08;邊&#xff09;以及屬性&#xff08;鍵值對&#xff09;構成的圖形數據模型。它的核心優勢在于能夠以一種自然且…

學習MySQL的第十天

一、MySQL的數據類型 1.MySQL的數據類型 2.常見的數據類型的屬性 二、整數類型 三、浮點類型 REAL默認就是DOUBLE。如果你把SQL模式設定為啟用“REAL_AS_FLOAT”,那么,MySQL就認為REAL是FLOAT。如果要啟用“REAL_AS_FLOAT”,可以通過以下SQL語句實現: SET sql_mode &…

ubuntu24.04上使用qemu+buildroot+uboot+linux+tftp+nfs模擬搭建vexpress-ca9嵌入式linux開發環境

1 準備工作 1.1 安裝依賴工具 sudo apt-get update && sudo apt-get install build-essential git bc flex libncurses5-dev libssl-dev device-tree-compiler1.2 安裝arm交叉編譯工具鏈 sudo apt install gcc-arm-linux-gnueabihf安裝之后&#xff0c;在終端輸入ar…

ubuntu 22.04 使用ssh-keygen創建ssh互信賬戶

現有兩臺ubuntu 22.04服務器&#xff0c;ip分別為192.168.66.88和192.168.88.66。需要將兩臺服務器創建新用戶并將新用戶做互信。 創建賬戶 adduser user1 # 如果此用戶不想使用密碼&#xff0c;直接一直回車就行&#xff0c;創建的用戶是沒法使用用戶密碼進行登陸的 su - …

【PCIE配置空間】

1 PCIE配置空間 1.1 軟件如何知道PCIE設備是Swith&#xff0c;RC還是EP&#xff1f; –軟件通過讀取寄存器信息。 PCIE配置空間? PCIE寄存器&#xff1b;--PCIE配置協議規定必須實現的空間。--PCIE存在兩種配置空間Type0/Type1;--Type0配置空間EP設備必須實現&#xff1b;-…

Android 熱點二維碼簡單示例

Android 熱點二維碼簡單示例 一、前言 Android 原生設置有熱點二維碼分享功能&#xff0c;有些系統應用也會有這個需求。 下面看看是如何實現的。 本文是一個比較簡單的內容。 二、熱點二維碼生成實現 1、效果 整個應用就一個普通的Activity&#xff0c;顯示一個按鈕和二維…

uv:重新定義Python開發效率的下一代工具鏈

在Python生態系統中&#xff0c;包管理和項目工具鏈的復雜性一直是開發者面臨的一大挑戰。從依賴管理、虛擬環境創建到多版本Python切換&#xff0c;傳統的工具鏈&#xff08;如pip、virtualenv、poetry等&#xff09;雖然功能強大&#xff0c;但操作繁瑣、性能不足的問題長期存…

T101D加固平板電腦:無人機地面站的高效智能控制核心

隨著無人機技術在應急救援、農業監測、軍事偵察等領域的廣泛應用&#xff0c;對地面控制設備的要求也日益提高。魯成偉業推出的T101D加固平板電腦憑借其高性能、強防護和專業化設計&#xff0c;成為無人機地面站的核心控制終端&#xff0c;為復雜環境下的作業提供了可靠支持。 …

Datawhale AI春訓營】AI + 新能源(發電功率預測)Task1

賽題鏈接 官網 新能源發電功率預測賽題進階方案 下面是ai給的一些建議 新能源發電功率預測賽題進階方案 一、時序特性深度挖掘 1. 多尺度周期特征 # 分鐘級周期編碼 train[15min_index] (train[hour]*4 train[minute]//15)# 周周期特征 train[weekday] pd.to_datetime…

山東科技大學深度學習考試回憶

目錄 一、填空&#xff08;五個空&#xff0c;十分&#xff09; 二、選擇題(五個&#xff0c;十分&#xff09; 三、判斷題&#xff08;五個&#xff0c;五分&#xff09; 四、論述題&#xff08;四個&#xff0c;四十分&#xff09; 五、計算題&#xff08;二個&#xff…

Redis線上操作最佳實踐有哪些?

大家好&#xff0c;我是鋒哥。今天分享關于【Redis線上操作最佳實踐有哪些?】面試題。希望對大家有幫助&#xff1b; Redis線上操作最佳實踐有哪些? 1000道 互聯網大廠Java工程師 精選面試題-Java資源分享網 在使用 Redis 時&#xff0c;尤其是在生產環境中&#xff0c;合理…

mac中的zip文件壓縮與壓縮文件中指定目錄刪除

問題 在使用mac的圖形界面壓縮文件后&#xff0c;往往那個壓縮文件中帶有__MACOSX文件&#xff0c;但是&#xff0c;這個文件夾又是我們不需要的目錄&#xff0c;所有&#xff0c;需要對mac圖形化界面壓縮后的文件目錄進行刪除&#xff0c;改如何做&#xff1f; 檢查壓縮文件…

【記錄】服務器用命令開啟端口號

這里記錄下如何在服務器上開啟適用于外界訪問的端口號。 方法 1 使用防火墻 1 su &#xff0c;命令 輸入密碼 切換到root節點 2 開啟防火墻 systemctl start firewalld3 配置開放端口 firewall-cmd --zonepublic --add-port8282/tcp --permanent4 重啟防火墻 firewall-cmd…

深度學習-torch,全連接神經網路

3. 數據集加載案例 通過一些數據集的加載案例&#xff0c;真正了解數據類及數據加載器。 3.1 加載csv數據集 代碼參考如下 import torch from torch.utils.data import Dataset, DataLoader import pandas as pd ? ? class MyCsvDataset(Dataset):def __init__(self, fil…