国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

力扣:494. 目標(biāo)和(動(dòng)態(tài)規(guī)劃)(01背包)

這篇具有很好參考價(jià)值的文章主要介紹了力扣:494. 目標(biāo)和(動(dòng)態(tài)規(guī)劃)(01背包)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

題目:

給你一個(gè)非負(fù)整數(shù)數(shù)組 nums 和一個(gè)整數(shù) target 。

向數(shù)組中的每個(gè)整數(shù)前添加 ‘+’ 或 ‘-’ ,然后串聯(lián)起所有整數(shù),可以構(gòu)造一個(gè) 表達(dá)式

例如,nums = [2, 1] ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-’ ,然后串聯(lián)起來得到表達(dá)式 “+2-1” 。
返回可以通過上述方法構(gòu)造的、運(yùn)算結(jié)果等于 target 的不同 表達(dá)式 的數(shù)目。

示例 1:

輸入:

nums = [1,1,1,1,1], target = 3

輸出:

5

解釋:

一共有 5 種方法讓最終目標(biāo)和為 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

思路:

本題可以用回溯來解決(但是會超時(shí)),也可以用動(dòng)態(tài)規(guī)劃中的01背包來解決,
如何轉(zhuǎn)化為01背包問題呢。

假設(shè)加法的總和為x,那么減法對應(yīng)的總和就是sum - x。

所以我們要求的是 x - (sum - x) = target

x = (target + sum) / 2

此時(shí)問題就轉(zhuǎn)化為,裝滿容量為x的背包,有幾種方法。

這里的x,就是bagSize,也就是我們后面要求的背包容量。

大家看到(target + sum) / 2 應(yīng)該擔(dān)心計(jì)算的過程中向下取整有沒有影響。

這么擔(dān)心就對了,例如sum 是5,S是2的話其實(shí)就是無解的,所以:

        # 如果nums的和與target的和的奇偶性不同,無法得到目標(biāo)和為target的子集
        if (sum(nums) + target) % 2 == 1:
            return 0

同時(shí)如果 S的絕對值已經(jīng)大于sum,那么也是沒有方案的。

        # 如果目標(biāo)和的絕對值大于nums的和,無法得到目標(biāo)和為target的子集
        if abs(target) > sum(nums):
            return 0

再回歸到01背包問題,為什么是01背包呢?

因?yàn)槊總€(gè)物品(題目中的1)只用一次

這次和之前遇到的背包問題不一樣了,之前都是求容量為j的背包,最多能裝多少。

本題則是裝滿有幾種方法。其實(shí)這就是一個(gè)組合問題了。

動(dòng)態(tài)規(guī)劃五部曲

  1. 確定dp數(shù)組以及下標(biāo)的含義

dp[j] 表示:填滿j(包括j)這么大容積的包,有dp[j]種方法

  1. 確定遞推公式

有哪些來源可以推出dp[j]呢?

只要搞到nums[i],湊成dp[j]就有dp[j - nums[i]] 種方法。

例如:dp[j],j 為5,

  • 已經(jīng)有一個(gè)1(nums[i]) 的話,有 dp[4]種方法 湊成 dp[5]。
  • 已經(jīng)有一個(gè)2(nums[i]) 的話,有 dp[3]種方法 湊成 dp[5]。
  • 已經(jīng)有一個(gè)3(nums[i]) 的話,有 dp[2]中方法 湊成 dp[5]。
  • 已經(jīng)有一個(gè)4(nums[i]) 的話,有 dp[1]中方法 湊成 dp[5]。
  • 已經(jīng)有一個(gè)5(nums[i]) 的話,有 dp[0]中方法 湊成 dp[5]。

那么湊整dp[5]有多少方法呢,也就是把 所有的 dp[j - nums[i]] 累加起來。

dp[j] += dp[j - nums[i]]

這個(gè)跟爬樓梯(力扣:70爬樓梯)和不同路徑(力扣:62.不同路徑)的思路有點(diǎn)類似,現(xiàn)在在重新分析一下:
現(xiàn)在有dp[4]種方法湊成4,你手上還有一個(gè)數(shù)字1,那么湊成5的話有幾種方法? 還是dp[4]種方法!為什么不是dp[4] + 1 種方法呢?因?yàn)檫@個(gè)數(shù)字1是確定只能是+1,而不能是-1,只有一種方法使4變成5。可以這樣理解,這里的方法數(shù)量最后是dp[4] * 1,
如果這里1可以是+1也可以是-1的話那方法數(shù)量應(yīng)該是dp[4] * 2

同理,有dp[3]種方法湊成3,現(xiàn)在手上還有一個(gè)2,那么有幾種方法湊成5?還是dp[3]種!

  1. dp數(shù)組如何初始化

從遞推公式可以看出,在初始化的時(shí)候dp[0] 一定要初始化為1,因?yàn)閐p[0]是在公式中一切遞推結(jié)果的起源,如果dp[0]是0的話,遞推結(jié)果將都是0。

這里有錄友可能認(rèn)為從dp數(shù)組定義來說 dp[0] 應(yīng)該是0,也有錄友認(rèn)為dp[0]應(yīng)該是1。

其實(shí)不要硬去解釋它的含義,咱就把 dp[0]的情況帶入本題看看應(yīng)該等于多少。

如果數(shù)組[0] ,target = 0,那么 bagSize = (target + sum) / 2 = 0。 dp[0]也應(yīng)該是1, 也就是說給數(shù)組里的元素 0 前面無論放加法還是減法,都是 1 種方法。

所以本題我們應(yīng)該初始化 dp[0] 為 1。

  1. 確定遍歷順序

毋庸置疑,對于01背包問題一維dp的遍歷,nums放在外循環(huán),target在內(nèi)循環(huán),且內(nèi)循環(huán)倒序。

  1. 舉例推導(dǎo)dp數(shù)組

輸入:nums: [1, 1, 1, 1, 1], S: 3

bagSize = (S + sum) / 2 = (3 + 5) / 2 = 4

dp數(shù)組狀態(tài)變化如下:
力扣:494. 目標(biāo)和(動(dòng)態(tài)規(guī)劃)(01背包),python,算法,leetcode,動(dòng)態(tài)規(guī)劃,python,算法

代碼及詳細(xì)注釋:

一維dp數(shù)組:

class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        # 如果nums的和與target的和的奇偶性不同,無法得到目標(biāo)和為target的子集
        if (sum(nums) + target) % 2 == 1:
            return 0
        # 如果目標(biāo)和的絕對值大于nums的和,無法得到目標(biāo)和為target的子集
        if abs(target) > sum(nums):
            return 0
        # 計(jì)算S,S為目標(biāo)和
        S = (target + sum(nums)) // 2
        # 創(chuàng)建一個(gè)長度為S+1的數(shù)組dp,用于記錄可以得到和為i的子集的個(gè)數(shù)
        dp = [0] * (S + 1)
        dp[0] = 1  # 初始化dp[0]為1
        # 遍歷nums中的每個(gè)數(shù)字
        for i in range(len(nums)):
            # 從S到nums[i]遍歷,更新dp數(shù)組
            for j in range(S, nums[i] - 1, -1):
                # 更新dp[j]的值
                dp[j] += dp[j - nums[i]]
        # 返回dp[S],表示可以得到和為S的子集的個(gè)數(shù)
        return dp[S]

  • 時(shí)間復(fù)雜度:O(n × m),n為正數(shù)個(gè)數(shù),m為背包容量
  • 空間復(fù)雜度:O(m),m為背包容量

回溯版本:文章來源地址http://www.zghlxwxcb.cn/news/detail-812417.html

class Solution:


    def backtracking(self, candidates, target, total, startIndex, path, result):
        if total == target:
            result.append(path[:])  # 將當(dāng)前路徑的副本添加到結(jié)果中
        # 如果 sum + candidates[i] > target,則停止遍歷
        for i in range(startIndex, len(candidates)):
            if total + candidates[i] > target:
                break
            total += candidates[i]
            path.append(candidates[i])
            self.backtracking(candidates, target, total, i + 1, path, result)
            total -= candidates[i]
            path.pop()

    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        total = sum(nums)
        if target > total:
            return 0  # 此時(shí)沒有方案
        if (target + total) % 2 != 0:
            return 0  # 此時(shí)沒有方案,兩個(gè)整數(shù)相加時(shí)要注意數(shù)值溢出的問題
        bagSize = (target + total) // 2  # 轉(zhuǎn)化為組合總和問題,bagSize就是目標(biāo)和

        # 以下是回溯法代碼
        result = []
        nums.sort()  # 需要對nums進(jìn)行排序
        self.backtracking(nums, bagSize, 0, 0, [], result)
        return len(result)


到了這里,關(guān)于力扣:494. 目標(biāo)和(動(dòng)態(tài)規(guī)劃)(01背包)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 動(dòng)態(tài)規(guī)劃 Leetcode 494 目標(biāo)和

    Leetcode 494 學(xué)習(xí)記錄自代碼隨想錄 要點(diǎn):1.想到±代表其實(shí)求的是連個(gè)組合的差值,進(jìn)而記left為正組合,right為負(fù)組合,則有 { l e f t ? r i g h t = t a r g e t l e f t + r i g h t = s u m left { begin{matrix} left-right=target \\\\ left+right=sum end{matrix} right . { l e f t ? r i g h t = t a r g e t l e f t + r

    2024年04月09日
    瀏覽(17)
  • leetCode 2915. 和為目標(biāo)值的最長子序列的長度 + 動(dòng)態(tài)規(guī)劃 +01背包 + 空間優(yōu)化 + 記憶化搜索 + 遞推

    leetCode 2915. 和為目標(biāo)值的最長子序列的長度 + 動(dòng)態(tài)規(guī)劃 +01背包 + 空間優(yōu)化 + 記憶化搜索 + 遞推

    2915. 和為目標(biāo)值的最長子序列的長度 - 力扣(LeetCode) 給你一個(gè)下標(biāo)從? 0 ?開始的整數(shù)數(shù)組? nums ?和一個(gè)整數(shù)? target ?。返回和為? target ?的? nums ?子序列中,子序列? 長度的最大值? 。如果不存在和為? target ?的子序列,返回? -1 ?。 子序列 ?指的是從原數(shù)組中刪除一些

    2024年02月06日
    瀏覽(25)
  • 力扣:474. 一和零(動(dòng)態(tài)規(guī)劃)(01背包)

    力扣:474. 一和零(動(dòng)態(tài)規(guī)劃)(01背包)

    給你一個(gè)二進(jìn)制字符串?dāng)?shù)組 strs 和兩個(gè)整數(shù) m 和 n 。 請你找出并返回 strs 的最大子集的長度,該子集中 最多 有 m 個(gè) 0 和 n 個(gè) 1 。 如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。 示例 1 : 輸入: strs = [“10”, “0001”, “111001”, “1”, “0”], m = 5, n = 3 輸出:

    2024年01月22日
    瀏覽(20)
  • 力扣第474題 一和零 c++ 動(dòng)態(tài)規(guī)劃 01背包

    474. 一和零 中等 相關(guān)標(biāo)簽 數(shù)組? ?字符串? ?動(dòng)態(tài)規(guī)劃 給你一個(gè)二進(jìn)制字符串?dāng)?shù)組? strs ?和兩個(gè)整數(shù)? m ?和? n ?。 請你找出并返回? strs ?的最大子集的長度,該子集中? 最多 ?有? m ?個(gè)? 0 ?和? n ?個(gè)? 1 ?。 如果? x ?的所有元素也是? y ?的元素,集合? x ?是集合? y

    2024年02月06日
    瀏覽(27)
  • 【Day43】代碼隨想錄之動(dòng)態(tài)規(guī)劃0-1背包_1049. 最后一塊石頭的重量 II_494. 目標(biāo)和_ 474.一和零

    動(dòng)態(tài)規(guī)劃理論基礎(chǔ) 動(dòng)規(guī)五部曲: 確定dp數(shù)組 下標(biāo)及dp[i] 的含義。 遞推公式:比如斐波那契數(shù)列 dp[i] = dp[i-1] + dp[i-2]。 初始化dp數(shù)組。 確定遍歷順序:從前到后or其他。 打印。 出現(xiàn)結(jié)果不正確: 打印dp日志和自己想的一樣:遞推公式、初始化或者遍歷順序出錯(cuò)。 打印dp日志和

    2024年02月22日
    瀏覽(24)
  • 力扣第1049題 最后一塊石頭的重量Il c++ 動(dòng)態(tài)規(guī)劃(01背包)

    1049. 最后一塊石頭的重量 II 中等 相關(guān)標(biāo)簽 有一堆石頭,用整數(shù)數(shù)組? stones ?表示。其中? stones[i] ?表示第? i ?塊石頭的重量。 每一回合,從中選出 任意兩塊石頭 ,然后將它們一起粉碎。假設(shè)石頭的重量分別為? x ?和? y ,且? x = y 。那么粉碎的可能結(jié)果如下: 如果? x

    2024年02月06日
    瀏覽(19)
  • 算法競賽必考算法——?jiǎng)討B(tài)規(guī)劃(01背包和完全背包)

    算法競賽必考算法——?jiǎng)討B(tài)規(guī)劃(01背包和完全背包)

    1.1題目介紹 1.2思路一介紹(二維數(shù)組) 代碼如下: 1.3思路二介紹(一維數(shù)組) 空間優(yōu)化 ??為什么可以使用一維數(shù)組? ??我們先來看一看01背包問題的狀態(tài)轉(zhuǎn)移方程,我們可以發(fā)現(xiàn) f[i]只用到了f[i-1],其他的是沒有用到的,我們可以用滾動(dòng)數(shù)組來做。 ??還有一個(gè)原因就是我

    2024年02月02日
    瀏覽(23)
  • 算法學(xué)習(xí)——LeetCode力扣動(dòng)態(tài)規(guī)劃篇3(494. 目標(biāo)和、474. 一和零、518. 零錢兌換 II)

    算法學(xué)習(xí)——LeetCode力扣動(dòng)態(tài)規(guī)劃篇3(494. 目標(biāo)和、474. 一和零、518. 零錢兌換 II)

    494. 目標(biāo)和 - 力扣(LeetCode) 描述 給你一個(gè)非負(fù)整數(shù)數(shù)組 nums 和一個(gè)整數(shù) target 。 向數(shù)組中的每個(gè)整數(shù)前添加 ‘+’ 或 ‘-’ ,然后串聯(lián)起所有整數(shù),可以構(gòu)造一個(gè) 表達(dá)式 : 例如,nums = [2, 1] ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-’ ,然后串聯(lián)起來得到表達(dá)式 “

    2024年04月14日
    瀏覽(70)
  • 算法系列--動(dòng)態(tài)規(guī)劃--背包問題(1)--01背包介紹

    算法系列--動(dòng)態(tài)規(guī)劃--背包問題(1)--01背包介紹

    ??\\\"趁著年輕,做一些比較cool的事情\\\"?? 作者:Lvzi 文章主要內(nèi)容:算法系列–動(dòng)態(tài)規(guī)劃–背包問題(1)–01背包介紹 大家好,今天為大家?guī)淼氖?算法系列--動(dòng)態(tài)規(guī)劃--背包問題(1)--01背包介紹 背包問題是動(dòng)態(tài)規(guī)劃中經(jīng)典的一類問題,經(jīng)常在筆試面試中出現(xiàn),是非常 具有區(qū)分度 的題

    2024年04月16日
    瀏覽(93)
  • 算法學(xué)習(xí)筆記(動(dòng)態(tài)規(guī)劃——01背包)

    先來聊聊動(dòng)態(tài)規(guī)劃,動(dòng)態(tài)規(guī)劃是分治法的一種體現(xiàn),把一個(gè)問題分解成若干個(gè)子集,通過當(dāng)前狀態(tài),經(jīng)過操作得到下一個(gè)狀態(tài),最后得到最優(yōu)問題解的一種方法。 步驟: 設(shè)定狀態(tài),保存狀態(tài) 根據(jù)狀態(tài)設(shè)定轉(zhuǎn)移方程 確定邊界 其中的01背包解決的是關(guān)于選擇的動(dòng)態(tài)規(guī)劃問題,

    2024年03月25日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包