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

day43 | 1049. 最后一塊石頭的重量 II、494. 目標(biāo)和、474.一和零

這篇具有很好參考價(jià)值的文章主要介紹了day43 | 1049. 最后一塊石頭的重量 II、494. 目標(biāo)和、474.一和零。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄:

解題及思路學(xué)習(xí)

1049. 最后一塊石頭的重量 II

有一堆石頭,用整數(shù)數(shù)組?stones?表示。其中?stones[i]?表示第?i?塊石頭的重量。

每一回合,從中選出任意兩塊石頭,然后將它們一起粉碎。假設(shè)石頭的重量分別為?x?和?y,且?x <= y。那么粉碎的可能結(jié)果如下:

  • 如果?x == y,那么兩塊石頭都會(huì)被完全粉碎;
  • 如果?x != y,那么重量為?x?的石頭將會(huì)完全粉碎,而重量為?y?的石頭新重量為?y-x

最后,最多只會(huì)剩下一塊?石頭。返回此石頭?最小的可能重量?。如果沒(méi)有石頭剩下,就返回?0

示例 1:

輸入:stones = [2,7,4,1,8,1]
輸出:1

思考:要剩下的石頭盡可能重量小,所以就是背包的重量盡可能接近總值的一半。

隨想錄:

1、dp[j] 表示背包容量為j的最大價(jià)值dp[j]. 本題中價(jià)值等于重量,所以也就是最大重量dp[j].

2、dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); ? dp[j] = max(dp[j], dp[j-stone[i]] + ston[i]);

3、初始化。dp[0] = 0, 非零下標(biāo)初始化為0.

4、確定遍歷順序。第一層for循環(huán)遍歷的是物品,第二層for循環(huán)遍歷的是背包。為了保證所有物品只放了一次,所以是從大到小去遍歷。(如果從小大遍歷就是完全背包了)

5、舉例推導(dǎo)dp數(shù)組

舉例,輸入:[2,4,1,1],此時(shí)target = (2 + 4 + 1 + 1)/2 = 4 ,dp數(shù)組狀態(tài)圖如下:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-2apHXva6-1688570040937)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/b43630c5-e46b-43c0-b83f-c12a514651db/Untitled.png)]

代碼:

class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        vector<int> dp(15001, 0);
        int sum = 0;
        for (int i = 0; i < stones.size(); i++) sum += stones[i];
        int target = sum / 2;
        for (int i = 0; i < stones.size(); i++) { // 遍歷物品
            for (int j = target; j >= stones[i]; j--) { // 遍歷背包
                dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);
            }
        }
        return sum - dp[target] - dp[target];
    }
};
  • 時(shí)間復(fù)雜度:O(m × n) , m是石頭總重量(準(zhǔn)確的說(shuō)是總重量的一半),n為石頭塊數(shù)
  • 空間復(fù)雜度:O(m)

這道題dp的定義很關(guān)鍵,是容量為j的時(shí)候,所能裝的最大價(jià)值(重量)。注意容量不一定都要用完j。

494. 目標(biāo)和

https://leetcode.cn/problems/target-sum/

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

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

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

返回可以通過(guò)上述方法構(gòu)造的、運(yùn)算結(jié)果等于?target?的不同?表達(dá)式?的數(shù)目。

示例 1:

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

思考:思不開(kāi),想不到。

隨想錄:nums里面的數(shù)組可以分為正數(shù)類(lèi)集合(left) 和負(fù)數(shù)類(lèi)集合 (right) 。那么有→

left + right = sum , left - right = target. ? left = (sum + target) /2;

當(dāng) (sum + target) 不能整除2的時(shí)候,說(shuō)明不滿足條件,返回0。 再dp過(guò)程中要盡量能夠是正數(shù)這個(gè)集合(背包)裝滿。本題相當(dāng)于是給我們一個(gè)背包容量,有多少種方式能把背包裝滿。此時(shí)問(wèn)題就轉(zhuǎn)化為,裝滿容量為x的背包,有幾種方法。

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

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

1、dp[j] 裝滿背包容量為j , 有dp[j]種方法。

2、dp[j] += dp[j-nums[i]]。

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

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

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

3、dp[0] = 1; 非零下標(biāo)初始化為0.

4、遍歷順序。第一層遍歷物品,第二層遍歷背包。倒序。

5、舉例推導(dǎo)dp數(shù)組

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

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

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-Le1tJjWa-1688570040941)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/2fae4be7-6fe7-4f58-a02f-21ede6495323/Untitled.png)]

代碼:

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int S) {
        int sum = 0;
        for (int i = 0; i < nums.size(); i++) sum += nums[i];
        if (abs(S) > sum) return 0; // 此時(shí)沒(méi)有方案
        if ((S + sum) % 2 == 1) return 0; // 此時(shí)沒(méi)有方案
        int bagSize = (S + sum) / 2;
        vector<int> dp(bagSize + 1, 0);
        dp[0] = 1;
        for (int i = 0; i < nums.size(); i++) {
            for (int j = bagSize; j >= nums[i]; j--) {
                dp[j] += dp[j - nums[i]];
            }
        }
        return dp[bagSize];
    }
};
  • 時(shí)間復(fù)雜度:O(n × m),n為正數(shù)個(gè)數(shù),m為背包容量
  • 空間復(fù)雜度:O(m),m為背包容量

個(gè)人感覺(jué)上面的遞推公式那里有一定的誤導(dǎo)性。幾個(gè)nums[i] 會(huì)讓人覺(jué)得只跟nums[i] 的個(gè)數(shù)有關(guān),但其實(shí)是和nums[i]中的數(shù)值有關(guān)。如果例如nums[i] 是2的話,那么dp[j] += dp[j-2] 。給的例子中只是因?yàn)槎际?這種巧合。 所以應(yīng)該是: 背包容量已經(jīng)有了2的話, 那么剩下j-2 容量,所以是dp[j-2]種填滿方法。

474.一和零

https://leetcode.cn/problems/ones-and-zeroes/

給你一個(gè)二進(jìn)制字符串?dāng)?shù)組?strs?和兩個(gè)整數(shù)?m?和?n?。

請(qǐng)你找出并返回?strs?的最大子集的長(zhǎng)度,該子集中?最多?有?m?個(gè)?0?和?n?個(gè)?1?。

如果?x?的所有元素也是?y?的元素,集合?x?是集合?y?的?子集?。

示例 1:

輸入:strs = ["10", "0001", "111001", "1", "0"], m = 5, n = 3
輸出:4

思考:最大子集,感覺(jué)是要填兩個(gè)背包m和n。填這兩個(gè)背包種記錄一個(gè)最大子集長(zhǎng)度。

隨想錄:要裝滿m和0,n個(gè)1這么大容器的背包,這個(gè)背包里面最多有多少個(gè)物品。

本題中strs 數(shù)組里的元素就是物品,每個(gè)物品都是一個(gè)!

而m 和 n相當(dāng)于是一個(gè)背包,兩個(gè)維度的背包

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

    dp[i][j]:最多有i個(gè)0和j個(gè)1的strs的最大子集的大小為dp[i][j]。

  2. 確定遞推公式

    dp[i][j] 可以由前一個(gè)strs里的字符串推導(dǎo)出來(lái),strs里的字符串有zeroNum個(gè)0,oneNum個(gè)1。

    dp[i][j] 就可以是 dp[i - zeroNum][j - oneNum] + 1。

    然后我們?cè)诒闅v的過(guò)程中,取dp[i][j]的最大值。

    所以遞推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);

    此時(shí)大家可以回想一下01背包的遞推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

    對(duì)比一下就會(huì)發(fā)現(xiàn),字符串的zeroNum和oneNum相當(dāng)于物品的重量(weight[i]),字符串本身的個(gè)數(shù)相當(dāng)于物品的價(jià)值(value[i])。

    這就是一個(gè)典型的01背包!?只不過(guò)物品的重量有了兩個(gè)維度而已。

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

    01背包的dp數(shù)組初始化為0就可以。

    因?yàn)槲锲穬r(jià)值不會(huì)是負(fù)數(shù),初始為0,保證遞推的時(shí)候dp[i][j]不會(huì)被初始值覆蓋。

  4. 確定遍歷順序

    外層for循環(huán)遍歷物品,內(nèi)層for循環(huán)遍歷背包容量且從后向前遍歷!

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

    以輸入:[“10”,“0001”,“111001”,“1”,“0”],m = 3,n = 3為例

    最后dp數(shù)組的狀態(tài)如下所示:

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-vSq8a5GR-1688570040943)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c563df54-a1a7-49bf-a001-3f6555d9eef8/Untitled.png)]

代碼:

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
        vector<vector<int>> dp(m + 1, vector<int> (n + 1, 0)); // 默認(rèn)初始化0
        for (string str : strs) { // 遍歷物品
            int oneNum = 0, zeroNum = 0;
            for (char c : str) {
                if (c == '0') zeroNum++;
                else oneNum++;
            }
            for (int i = m; i >= zeroNum; i--) { // 遍歷背包容量且從后向前遍歷!
                for (int j = n; j >= oneNum; j--) {
                    dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
                }
            }
        }
        return dp[m][n];
    }
};
  • 時(shí)間復(fù)雜度: O(kmn),k 為strs的長(zhǎng)度
  • 空間復(fù)雜度: O(mn)

知識(shí)點(diǎn)記錄

知識(shí)點(diǎn)

此時(shí)我們講解了0-1背包的多種應(yīng)用,

  • **純 0 - 1 背包?(opens new window)**是求 給定背包容量 裝滿背包 的最大價(jià)值是多少。
  • **416. 分割等和子集?(opens new window)**是求 給定背包容量,能不能裝滿這個(gè)背包。
  • **1049. 最后一塊石頭的重量 II?(opens new window)**是求 給定背包容量,盡可能裝,最多能裝多少
  • **494. 目標(biāo)和?(opens new window)**是求 給定背包容量,裝滿背包有多少種方法。
  • 本題是求 給定背包容量,裝滿背包最多有多少個(gè)物品。

以上是0-1背包不同維度上的應(yīng)用。

個(gè)人反思

背包問(wèn)題,好復(fù)雜!

上述應(yīng)該把0-1背包常見(jiàn)的問(wèn)題給總結(jié)了??梢远嗳パ芯恳幌逻@幾道題,多看幾遍體會(huì)一下。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-524623.html

到了這里,關(guān)于day43 | 1049. 最后一塊石頭的重量 II、494. 目標(biāo)和、474.一和零的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 代碼隨想錄Day36 動(dòng)態(tài)規(guī)劃05 LeetCode T1049最后一塊石頭的重量II T494 目標(biāo)和 T474 一和零

    代碼隨想錄Day36 動(dòng)態(tài)規(guī)劃05 LeetCode T1049最后一塊石頭的重量II T494 目標(biāo)和 T474 一和零

    理論基礎(chǔ)? :?代碼隨想錄Day34 LeetCode T343整數(shù)拆分 T96 不同的二叉搜索樹(shù)-CSDN博客 1.明白dp數(shù)組的含義 2.明白遞推公式的含義 3.初始化dp數(shù)組 4.注意dp數(shù)組的遍歷順序 5.打印dp數(shù)組排錯(cuò) 題目鏈接:1049. 最后一塊石頭的重量 II - 力扣(LeetCode) 這題我們?nèi)匀徊捎脛?dòng)規(guī)五部曲來(lái)寫(xiě),這題和

    2024年02月06日
    瀏覽(19)
  • 算法訓(xùn)練第四十三天|1049. 最后一塊石頭的重量 II 、494. 目標(biāo)和、474.一和零

    算法訓(xùn)練第四十三天|1049. 最后一塊石頭的重量 II 、494. 目標(biāo)和、474.一和零

    題目鏈接:1049. 最后一塊石頭的重量 II 參考:https://programmercarl.com/1049.%E6%9C%80%E5%90%8E%E4%B8%80%E5%9D%97%E7%9F%B3%E5%A4%B4%E7%9A%84%E9%87%8D%E9%87%8FII.html 題目難度:中等 有一堆石頭,每塊石頭的重量都是正整數(shù)。 每一回合,從中選出任意兩塊石頭,然后將它們一起粉碎。假設(shè)石頭的重量分

    2023年04月09日
    瀏覽(19)
  • [Leetcode] 416. 分割等和子集、1049. 最后一塊石頭的重量 II、494. 目標(biāo)和、474. 一和零

    內(nèi)容:今天復(fù)習(xí)下dp數(shù)組中的背包問(wèn)題 分割等和子集 - 能否裝滿 最后一塊石頭 - 盡可能裝滿 目標(biāo)和 - 有多少種方法裝 一和零 - 裝滿背包有多少個(gè)物品 416. 分割等和子集 10背包:用/不用;有容量;有價(jià)值 dp[j] : 容量為j,最大價(jià)值為dp[j] ? ? ? ? 重量和價(jià)值等價(jià) dp[target] == t

    2024年02月16日
    瀏覽(30)
  • 【5.31 代隨_43day】 最后一塊石頭的重量 II、目標(biāo)和、一和零

    【5.31 代隨_43day】 最后一塊石頭的重量 II、目標(biāo)和、一和零

    力扣連接:1049. 最后一塊石頭的重量 II(中等) 和 416. 分割等和子集 (opens new window) 非常像了 圖解步驟 代碼 力扣連接:494. 目標(biāo)和(中等) 確定dp數(shù)組以及下標(biāo)的含義 dp[j] 表示:填滿j(包括j)這么大容積的包,有dp[j]種方法 確定遞推公式 只要搞到nums[i],湊成dp[j]就有dp[

    2024年02月07日
    瀏覽(22)
  • leetcode 1049. 最后一塊石頭的重量 II

    leetcode 1049. 最后一塊石頭的重量 II

    ? ? ? ? ?與分割等和子集類(lèi)似,可以轉(zhuǎn)化為0-1背包問(wèn)題。 本題也是需要將數(shù)組元素分成兩堆,區(qū)別在于本題需要使這兩堆的差值最小,而之前那題是需要兩堆差值為0。 ? ? ? ?? 使用之前的一維dp數(shù)組的思路,代碼如下:

    2024年02月13日
    瀏覽(20)
  • LeetCode 1049 最后一塊石頭的重量 II

    題目: 有一堆石頭,用整數(shù)數(shù)組 stones 表示。其中 stones[i] 表示第 i 塊石頭的重量。每一回合,從中選出任意兩塊石頭,然后將它們一起粉碎。假設(shè)石頭的重量分別為 x 和 y,且 x = y。那么粉碎的可能結(jié)果如下: 如果 x == y,那么兩塊石頭都會(huì)被完全粉碎; 如果 x != y,那么重

    2024年02月05日
    瀏覽(30)
  • LeetCode1049. 最后一塊石頭的重量 II

    一、題目 有一堆石頭,用整數(shù)數(shù)組 stones 表示。其中 stones[i] 表示第 i 塊石頭的重量。 每一回合,從中選出 任意兩塊石頭 ,然后將它們一起粉碎。假設(shè)石頭的重量分別為 x 和 y ,且 x = y 。那么粉碎的可能結(jié)果如下: 如果 x == y ,那么兩塊石頭都會(huì)被完全粉碎; 如果 x != y ,

    2024年02月10日
    瀏覽(22)
  • Leetcode 1049 最后一塊石頭的重量II

    Leetcode 1049 最后一塊石頭的重量II

    題意理解 : ????????有一堆石頭,用整數(shù)數(shù)組? stones ?表示。其中? stones[i] ?表示第? i ?塊石頭的重量。 ????????每一回合,從中選出 任意兩塊石頭 ,然后將它們一起粉碎。假設(shè)石頭的重量分別為? x ?和? y ,且? x = y 。 ? ? ? ? 思路轉(zhuǎn)化:我們可以將題目轉(zhuǎn)換為

    2024年01月16日
    瀏覽(20)
  • Leet code1049 最后一塊石頭的重量II

    1049 最后一塊石頭的重量II 【問(wèn)題描述】 有一堆石頭,用整數(shù)數(shù)組 stones 表示。其中 stones[i] 表示第 i 塊石頭的重量。 每一回合,從中選出 任意兩塊石頭 ,然后將它們一起粉碎。假設(shè)石頭的重量分別為 x 和 y ,且 x = y 。那么粉碎的可能結(jié)果如下: 如果 x == y ,那么兩塊石頭

    2024年02月13日
    瀏覽(21)
  • 【算法練習(xí)Day36】最后一塊石頭的重量 II&&目標(biāo)和&&一和零

    【算法練習(xí)Day36】最后一塊石頭的重量 II&&目標(biāo)和&&一和零

    ???個(gè)人主頁(yè):@Sherry的成長(zhǎng)之路 ??學(xué)習(xí)社區(qū):Sherry的成長(zhǎng)之路(個(gè)人社區(qū)) ??專(zhuān)欄鏈接:練題 ?? 長(zhǎng)路漫漫浩浩,萬(wàn)事皆有期待 1049. 最后一塊石頭的重量 II - 力扣(LeetCode) 最后一塊石頭的重量II,這道題是將各個(gè)不同重量的石頭相互碰撞,碰撞規(guī)則是如果兩石頭重量一

    2024年02月06日
    瀏覽(19)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包