力扣每日一題 6/30 記憶化搜索/動態規劃

  • 博客主頁:誓則盟約
  • 系列專欄:IT競賽 專欄
  • 關注博主,后期持續更新系列文章
  • 如果有錯誤感謝請大家批評指出,及時修改
  • 感謝大家點贊👍收藏?評論??

494.目標和【中等

題目:

給你一個非負整數數組?nums?和一個整數?target?。

向數組中的每個整數前添加?'+'?或?'-'?,然后串聯起所有整數,可以構造一個?表達式?:

  • 例如,nums = [2, 1]?,可以在?2?之前添加?'+'?,在?1?之前添加?'-'?,然后串聯起來得到表達式?"+2-1"?。

返回可以通過上述方法構造的、運算結果等于?target?的不同?表達式?的數目。

示例 1:

輸入:nums = [1,1,1,1,1], target = 3
輸出:5
解釋:一共有 5 種方法讓最終目標和為 3 。
-1 + 1 + 1 + 1 + 1 = 3
+1 - 1 + 1 + 1 + 1 = 3
+1 + 1 - 1 + 1 + 1 = 3
+1 + 1 + 1 - 1 + 1 = 3
+1 + 1 + 1 + 1 - 1 = 3

示例 2:

輸入:nums = [1], target = 1
輸出:1

提示:

  • 1 <= nums.length <= 20
  • 0 <= nums[i] <= 1000
  • 0 <= sum(nums[i]) <= 1000
  • -1000 <= target <= 1000

分析問題:

設?nums?的元素和為?s,添加正號的元素之和為?p,添加負號的元素(絕對值)之和為?q,那么有

  • p+q=s
  • p-q=target

化簡得:

  • p = (s+target) / 2?
  • q = (s-target) / 2

? ? ? ? 我們找所有元素里面選取出來的元素和恰好為p的方案個數,那么這就變成了一道經典的0-1背包問題的變形,找恰好裝capacity,求方案數/最大/最小價值和,capacity指的是容量,也就是這里的負數的和的絕對值。

????????那么我們就可以根據傳統的0-1背包問題的求解過程來解題,帶上cache數組以便達到記憶化的一個效果。

????????此處也可以進行進一步的優化,用一個二維數組f來替代遞推函數dfs

????????首先創建一個二維數組f,其中n表示數組的長度,target表示目標值,該數組用于記錄不同狀態下的結果。

????????然后將f[0][0]初始化為1,這是一個基礎的起始條件。接下來通過兩個嵌套循環進行計算。外層循環遍歷一個名為nums的數組,其中的每個元素x代表物品的價值。內層循環遍歷目標值target的所有可能取值。在循環內部,根據不同條件更新f數組的值。

  • ????????如果c小于x,說明當前考慮的物品價值x大于當前的目標值c,無法選擇該物品,所以f[i + 1][c]保持與f[i][c]相同。
  • ????????如果c大于或等于x,那么f[i + 1][c]等于f[i][c]加上f[i][c - x],這表示在這種情況下,可以選擇該物品,所以要將不選擇該物品的情況(f[i][c])和選擇該物品的情況(f[i][c - x])的結果相加。

????????最后,函數返回f[n][target],即最終在考慮了所有物品和目標值的情況下的結果。

代碼實現:

優化前:
class Solution:def findTargetSumWays(self, nums: list[int], target: int) -> int:# p = (s+t) /2target += sum(nums)if target < 0 or target % 2:return 0target //=2n=len(nums)@cache  # 保存記憶def dfs(i,c): # i是剩余多少個物品沒裝      c是當前背包剩余容量if i<0:return 1 if c==0 else 0if c < nums[i]:return dfs(i-1,c)return dfs(i-1,c)+dfs(i-1,c-nums[i])return dfs(n-1,target)

?

優化后:
class Solution:def findTargetSumWays(self, nums: list[int], target: int) -> int:# p = (s+t) /2target += sum(nums)if target < 0 or target % 2:return 0target //=2n=len(nums)f=[[0]*(target+1) for _ in range(n+1)]f[0][0]=1for i,x in enumerate(nums):for c in range(target+1):if c<x: f[i+1][c] = f[i][c]else: f[i+1][c] = f[i][c] + f[i][c-x]return f[n][target]


?

總結:

優化后代碼詳細解釋
  1. target += sum(nums):將target值加上數組nums的元素總和,得到p的2倍。
  2. if target < 0 or target % 2::檢查新的target值是否小于0或是否為奇數。如果是,則直接返回0,表示無法得到目標值。
  3. target //= 2:將target值除以2,得到用于后續計算的新值。
  4. n = len(nums):獲取數組nums的長度。
  5. f = [[0] * (target + 1) for _ in range(n + 1)]:創建一個二維數組f,用于動態規劃的計算。
  6. f[0][0] = 1:設置初始狀態,即當沒有元素且目標值為0時,有一種方法可以達到。
  7. 通過兩個嵌套循環進行動態規劃計算:
    • 外層循環for i, x in enumerate(nums):遍歷數組nums的每個元素。
    • 內層循環for c in range(target + 1):遍歷所有可能的目標值。
    • 在循環內部,根據當前元素x和目標值c的關系更新f[i + 1][c]的值。如果c < x,則f[i + 1][c] = f[i][c],表示無法選擇當前元素來達到目標值;如果c >= x,則f[i + 1][c] = f[i][c] + f[i][c - x],表示可以選擇或不選擇當前元素來達到目標值,將兩種情況的方法數相加。
  8. 最后,函數返回f[n][target],即使用整個數組nums達到最終目標值的方法數。

考點

  1. 動態規劃的應用:通過構建二維數組來記錄不同狀態下的結果,根據狀態轉移方程進行計算。
  2. 對問題的數學轉化:將原問題轉化為通過加減運算得到特定值的問題,并進行了一些預處理和條件判斷。

收獲

  1. 深入理解了動態規劃的思想和應用方法,學會如何根據問題的特點構建合適的狀態和狀態轉移方程。
  2. 提高了對問題進行數學分析和轉化的能力,能夠將復雜的問題簡化為可計算的形式。
  3. 增強了對數組操作和循環的熟練程度,能夠靈活運用這些基本編程技巧來解決實際問題。

?“對于我們的幸福來說,別人的看法在本質上來講并不十分重要。”——《人生的智慧》

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

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

相關文章

VMware17.0 安裝過程

VMware17.0 VMware 17.0 是一款功能強大的虛擬機軟件&#xff0c;用于在計算機上創建和管理虛擬機。它能夠同時運行多個操作系統&#xff0c;如 Windows、Linux 等&#xff0c;并且在這些虛擬機之間提供無縫的切換和共享功能。 VMware 17.0 支持最新的硬件和操作系統&#xf…

Chrome瀏覽器web調試(js調試、css調試、篡改前置)

目錄 1. 打開開發者工具(Dev Tool) 2. 打開命令菜單 截圖 3. 面板介紹 4. CSS調試 右鍵檢查快速到達元素處 查找DOM數 利用面板Console查找DOM節點 內置函數查找上一個選擇點擊的元素 5. 調試JS代碼(Javascript調試) 日志調試 選擇查看日志等級 眼睛觀測變量 …

【Leetcode 67 Easy】二進制求和

目錄 題目描述&#xff1a; 整體思路&#xff1a; 具體代碼&#xff1a; 題目描述&#xff1a; 原題地址 給你兩個二進制字符串 a 和 b &#xff0c;以二進制字符串的形式返回它們的和。 示例 1&#xff1a; 輸入:a "11", b "1" 輸出&#xff1a;&qu…

ubuntu 18 虛擬機安裝(4)安裝 postgres sql 數據庫

ubuntu 18 虛擬機安裝&#xff08;4&#xff09;安裝 postgres sql 數據庫 如何查看PostgreSQL的版本 https://blog.csdn.net/lee_vincent1/article/details/138731465 postgres 查看全部數據庫 https://blog.csdn.net/xie__jin__cheng/article/details/138653002 Ubuntu18.04…

數據資產鑄就市場競爭優勢:運用先進的數據分析技術,精準把握市場脈搏,構建獨特的競爭優勢,助力企業實現市場領先地位,贏得持續成功

目錄 一、引言 二、數據資產的重要性 三、先進數據分析技術的應用 1、大數據分析技術 2、人工智能與機器學習 3、數據可視化技術 四、精準把握市場脈搏 1、深入了解客戶需求 2、預測市場趨勢 3、優化資源配置 五、構建獨特的競爭優勢 1、定制化產品和服務 2、精準營…

數據結構—判斷題

1.數據的邏輯結構說明數據元素之間的順序關系&#xff0c;它依賴于計算機的存儲結構。 答案&#xff1a;錯誤 2.(neuDS)在順序表中邏輯上相鄰的元素&#xff0c;其對應的物理位置也是相鄰的。 答案&#xff1a;正確 3.若一個棧的輸入序列為{1, 2, 3, 4, 5}&#xff0c;則不…

nginx上傳文件限制

默認限制 Nginx 限制文件大小可以通過 client_max_body_size 指令來設置&#xff0c;該指令通常在 http、server 或 location 塊中設置&#xff0c;如果不設置&#xff0c;默認上傳大小為1M。 修改上傳文件限制 要修改Nginx的文件上傳大小限制&#xff0c;你需要編輯Nginx的配…

接口自動化測試關聯token的方法?

引言&#xff1a; 在接口自動化測試中&#xff0c;有時候我們需要關聯token來進行身份驗證或權限管理。本文將從零開始&#xff0c;介紹如何詳細且規范地實現接口自動化測試中token的關聯。 步驟一&#xff1a;準備工作 在開始之前&#xff0c;我們需要確保以下準備工作已完成…

如何在 Linux 中后臺運行進程?

一、后臺進程 在后臺運行進程是 Linux 系統中的常見要求。在后臺運行進程允許您在進程獨立運行時繼續使用終端或執行其他命令。這對于長時間運行的任務或當您想要同時執行多個命令時特別有用。 在深入研究各種方法之前&#xff0c;讓我們先了解一下什么是后臺進程。在 Linux 中…

Kafka~特殊技術細節設計:分區機制、重平衡機制、Leader選舉機制、高水位HW機制

分區機制 Kafka 的分區機制是其實現高吞吐和可擴展性的重要特性之一。 Kafka 中的數據具有三層結構&#xff0c;即主題&#xff08;topic&#xff09;-> 分區&#xff08;partition&#xff09;-> 消息&#xff08;message&#xff09;。一個 Kafka 主題可以包含多個分…

3-linux命令行與基本命令

目錄 什么是shell linux命令 命令組成 幾個簡單的命令 linux文件系統導航 什么是shell linux學習路徑&#xff1a;學習shell→配置和環境→見任務和主要工具→編寫shell腳本 shell是一個接收由鍵盤輸入的命令&#xff0c;并將其傳遞給操作系統來執行的程序。幾乎所有…

C++學習全教程(Day2)

一、數組 在程序中為了處理方便,常常需要把具有相同類型的數據對象按有序的形式排列起來&#xff0c;形成“一組”數據&#xff0c;這就是“數組”(array&#xff09; 數組中的數據&#xff0c;在內存中是連續存放的&#xff0c;每個元素占據相同大小的空間&#xff0c;就像排…

【Spring】DAO 和 Repository 的區別

DAO 和 Repository 的區別 1.概述2.DAO 模式2.1 User2.2 UserDao2.3 UserDaoImpl 3.Repository 模式3.1 UserRepository3.2 UserRepositoryImpl 4.具有多個 DAO 的 Repository 模式4.1 Tweet4.2 TweetDao 和 TweetDaoImpl4.3 增強 User 域4.4 UserRepositoryImpl 5.比較兩種模式…

ISO 19110操作要求類中的/req/operation/formal-definition詳細解釋

/req/operation/formal-definition 要求: 每個要素操作實體必須具有一個形式定義&#xff08;formal definition&#xff09;&#xff0c;該定義應明確描述操作的行為和影響。 具體解釋 定義 要素操作實體&#xff08;feature operation entity&#xff09;&#xff1a;這…

深度學習基準模型Mamba

深度學習基準模型Mamba Mamba(英文直譯&#xff1a;眼鏡蛇)具有選擇性狀態空間的線性時間序列建模&#xff0c;是一種先進的狀態空間模型 (SSM)&#xff0c;專為高效處理復雜的數據密集型序列而設計。 Mamba是一種深度學習基準模型&#xff0c;專為處理長序列數據而設計&…

【鴻蒙學習筆記】位置設置

官方文檔&#xff1a;位置設置 目錄標題 align&#xff1a;子元素的對齊方式direction&#xff1a;官方文檔沒懂&#xff0c;看圖理解吧 align&#xff1a;子元素的對齊方式 Stack() {Text(TopStart)}.width(90%).height(50).backgroundColor(0xFFE4C4).align(Alignment.TopS…

<Python><ffmpeg>基于python使用PyQt5構建GUI實例:音頻格式轉換程序(MP3/aac/wma/flac)(優化版2)

前言 本文是基于python語言使用pyqt5來構建的GUI,功能是使用ffmpeg來對音頻文件進行格式轉換,如mp3、aac、wma、flac等音樂格式。 UI示例: 環境配置 系統:windows 平臺:visual studio code 語言:python 庫:pyqt5、ffmpeg 概述 本文是建立在之前的博文的基礎上的優化版…

在線教育項目(一):如何防止一個賬號多個地方登陸

使用jwt做驗證&#xff0c;使用賬號作為redis中的key,登錄的時候生成token放到redis中&#xff0c;每次申請資源的時候去看token 有沒有變&#xff0c;因為token每次登錄都會去覆蓋&#xff0c;只要第二次登錄token就不一樣了

Day7:.翻轉字符串里的單詞 151 卡碼網:55.右旋轉字符串

題目 151. 反轉字符串中的單詞 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:// 移除多余空格void moveSpace(string& s) {// 定義快慢指針int slow 0;int fast 0;// 刪除前導空格while (s.size() > 0 && fast < s.size() &&…