零基礎代碼隨想錄【Day42】|| 1049. 最后一塊石頭的重量 II,494. 目標和,474.一和零

目錄

DAY42

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

解題思路&代碼

494.目標和

解題思路&代碼

474.一和零

解題思路&代碼


DAY42

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

力扣題目鏈接(opens new window)

題目難度:中等

有一堆石頭,每塊石頭的重量都是正整數。

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

如果?x == y,那么兩塊石頭都會被完全粉碎;

如果?x != y,那么重量為?x?的石頭將會完全粉碎,而重量為?y?的石頭新重量為?y-x。

最后,最多只會剩下一塊石頭。返回此石頭最小的可能重量。如果沒有石頭剩下,就返回 0。

示例:

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

解釋:

  • 組合 2 和 4,得到 2,所以數組轉化為 [2,7,1,8,1],
  • 組合 7 和 8,得到 1,所以數組轉化為 [2,1,1,1],
  • 組合 2 和 1,得到 1,所以數組轉化為 [1,1,1],
  • 組合 1 和 1,得到 0,所以數組轉化為 [1],這就是最優值。

本題就和 昨天的 416. 分割等和子集 很像了,可以嘗試先自己思考做一做。

視頻講解:動態規劃之背包問題,這個背包最多能裝多少?LeetCode:1049.最后一塊石頭的重量II_嗶哩嗶哩_bilibili

代碼隨想錄

解題思路&代碼

思路:

關鍵點:認識到什么是應用類背包問題,此處如何聯系到背包?盡量把容器分成大小相等的兩堆,則另一堆是否能用數組元素填滿多少則是涉及到了背包最多能裝多少的問題

本題其實就是盡量讓石頭分成重量相同的兩堆,相撞之后剩下的石頭最小,這樣就化解成01背包問題了

是不是感覺和昨天講解的416. 分割等和子集?(opens new window)非常像了。

本題物品的重量為stones[i],物品的價值也為stones[i]。

對應著01背包里的物品重量weight[i]和 物品價值value[i]。

1.確定dp數組以及下標的含義

dp[j]表示容量(這里說容量更形象,其實就是重量)為j的背包,最多可以背最大重量為dp[j]

可以回憶一下01背包中,dp[j]的含義,容量為j的背包,最多可以裝的價值為 dp[j]。

2.確定遞推公式

01背包的遞推公式為:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

本題則是:dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);

3.dp數組如何初始化

既然 dp[j]中的j表示容量,那么最大容量(重量)是多少呢,就是所有石頭的重量和。

因為提示中給出1 <= stones.length <= 30,1 <= stones[i] <= 1000,所以最大重量就是30 * 1000 。

而我們要求的target其實只是最大重量的一半,所以dp數組開到15000大小就可以了

4.確定遍歷順序

在動態規劃:關于01背包問題,你該了解這些!(滾動數組)?(opens new window)中就已經說明:如果使用一維dp數組,物品遍歷的for循環放在外層,遍歷背包的for循環放在內層,且內層for循環倒序遍歷!

  • 時間復雜度:O(m × n) , m是石頭總重量(準確的說是總重量的一半),n為石頭塊數
  • 空間復雜度:O(m)
class Solution {public int lastStoneWeightII(int[] stones) {int sum = 0;for (int i : stones) {sum += i;}int target = sum >> 1;//初始化dp數組int[] dp = new int[target + 1];//為什么要+1,因為涉及到背包重量為0的情況,要初始化,但是實際上數組元素是不包括這個的for (int i = 0; i < stones.length; i++) {//采用倒序for (int j = target; j >= stones[i]; j--) {//兩種情況,要么放,要么不放dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);}}return sum - 2 * dp[target];}
}

494.目標和

力扣題目鏈接(opens new window)

難度:中等

給定一個非負整數數組,a1, a2, ..., an, 和一個目標數,S。現在你有兩個符號?+?和?-。對于數組中的任意一個整數,你都可以從?+?或?-中選擇一個符號添加在前面。

返回可以使最終數組和為目標數 S 的所有添加符號的方法數。

示例:

  • 輸入:nums: [1, 1, 1, 1, 1], S: 3
  • 輸出:5

解釋:

  • -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

一共有5種方法讓最終目標和為3。

大家重點理解 遞推公式:dp[j] += dp[j - nums[i]],這個公式后面的提問 我們還會用到。

視頻講解:動態規劃之背包問題,裝滿背包有多少種方法?| LeetCode:494.目標和_嗶哩嗶哩_bilibili

代碼隨想錄

?

解題思路&代碼

思路:

本題要如何使表達式結果為target,

既然為target,那么就一定有 left組合 - right組合 = target。

left + right = sum,而sum是固定的。right = sum - left

公式來了, left - (sum - left) = target 推導出 left = (target + sum)/2 。

target是固定的,sum是固定的,left就可以求出來。

此時問題就是在集合nums中找出和為left的組合

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

因為每個物品(題目中的1)只用一次!

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

本題則是裝滿有幾種方法。其實這就是一個組合問題了。

1.確定dp數組以及下標的含義

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

其實也可以使用二維dp數組來求解本題,dp[i][j]:使用 下標為[0, i]的nums[i]能夠湊滿j(包括j)這么大容量的包,有dp[i][j]種方法。

2.確定遞推公式

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

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

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

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

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

所以求組合類問題的公式,都是類似這種:

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

3.dp數組如何初始化

從遞推公式可以看出,在初始化的時候dp[0] 一定要初始化為1,因為dp[0]是在公式中一切遞推結果的起源,如果dp[0]是0的話,遞推結果將都是0。

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

所以本題我們應該初始化 dp[0] 為 1。

4.確定遍歷順序

在動態規劃:關于01背包問題,你該了解這些!(滾動數組)?(opens new window)中,我們講過對于01背包問題一維dp的遍歷,nums放在外循環,target在內循環,且內循環倒序。

5.舉例推導dp數組

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

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

dp數組狀態變化如下:

  • 時間復雜度:O(n × m),n為正數個數,m為背包容量
  • 空間復雜度:O(m),m為背包容量
class Solution {public int findTargetSumWays(int[] nums, int target) {int sum = 0;for (int i = 0; i < nums.length; i++) sum += nums[i];//如果target的絕對值大于sum,那么是沒有方案的if (Math.abs(target) > sum) return 0;//如果(target+sum)除以2的余數不為0,也是沒有方案的if ((target + sum) % 2 == 1) return 0;int bagSize = (target + sum) / 2;int[] dp = new int[bagSize + 1];dp[0] = 1;for (int i = 0; i < nums.length; i++) {for (int j = bagSize; j >= nums[i]; j--) {dp[j] += dp[j - nums[i]];}}return dp[bagSize];}
}

474.一和零

力扣題目鏈接(opens new window)

給你一個二進制字符串數組 strs 和兩個整數 m 和 n 。

請你找出并返回 strs 的最大子集的大小,該子集中 最多 有 m 個 0 和 n 個 1 。

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

示例 1:

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

  • 輸出:4

  • 解釋:最多有 5 個 0 和 3 個 1 的最大子集是 {"10","0001","1","0"} ,因此答案是 4 。 其他滿足題意但較小的子集包括 {"0001","1"} 和 {"10","1","0"} 。{"111001"} 不滿足題意,因為它含 4 個 1 ,大于 n 的值 3 。

通過這道題目,大家先粗略了解, 01背包,完全背包,多重背包的區別,不過不用細扣,因為后面 對于 完全背包,多重背包 還有單獨講解。

視頻講解:動態規劃之背包問題,裝滿這個背包最多用多少個物品?| LeetCode:474.一和零_嗶哩嗶哩_bilibili

代碼隨想錄

解題思路&代碼

思路:

本題并不是多重背包,再來看一下這個圖,捋清幾種背包的關系

416.分割等和子集1

多重背包是每個物品,數量不同的情況。

本題中strs 數組里的元素就是物品,每個物品都是一個!

而m 和 n相當于是一個背包,兩個維度的背包

理解成多重背包的同學主要是把m和n混淆為物品了,感覺這是不同數量的物品,所以以為是多重背包。

但本題其實是01背包問題!

只不過這個背包有兩個維度,一個是m 一個是n,而不同長度的字符串就是不同大小的待裝物品。

1.確定dp數組(dp table)以及下標的含義

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

2.確定遞推公式

dp[i][j] 可以由前一個strs里的字符串推導出來,strs里的字符串有zeroNum個0,oneNum個1。

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

然后我們在遍歷的過程中,取dp[i][j]的最大值。

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

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

對比一下就會發現,字符串的zeroNum和oneNum相當于物品的重量(weight[i]),字符串本身的個數相當于物品的價值(value[i])。

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

3.dp數組如何初始化

在動態規劃:關于01背包問題,你該了解這些!(滾動數組)?(opens new window)中已經講解了,01背包的dp數組初始化為0就可以。

因為物品價值不會是負數,初始為0,保證遞推的時候dp[i][j]不會被初始值覆蓋。

4.確定遍歷順序

在動態規劃:關于01背包問題,你該了解這些!(滾動數組)?(opens new window)中,我們講到了01背包為什么一定是外層for循環遍歷物品,內層for循環遍歷背包容量且從后向前遍歷!

那么本題也是,物品就是strs里的字符串,背包容量就是題目描述中的m和n。

  • 時間復雜度: O(kmn),k 為strs的長度
  • 空間復雜度: O(mn)?
class Solution {public int findMaxForm(String[] strs, int m, int n) {//dp[i][j]表示i個0和j個1時的最大子集int[][] dp = new int[m + 1][n + 1];int oneNum, zeroNum;for (String str : strs) {//正序遍歷物品oneNum = 0;zeroNum = 0;for (char ch : str.toCharArray()) {if (ch == '0') {zeroNum++;} else {oneNum++;}}//倒序遍歷背包容量for (int i = m; i >= zeroNum; i--) {for (int j = n; j >= oneNum; j--) {dp[i][j] = Math.max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);}}}return dp[m][n];}
}

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

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

相關文章

(Qt) 默認QtWidget應用包含什么?

文章目錄 ?前言?創建&#x1f6e0;?選擇一個模板&#x1f6e0;?Location&#x1f6e0;?構建系統&#x1f6e0;?Details&#x1f6e0;?Translation&#x1f6e0;?構建套件(Kit)&#x1f6e0;?匯總 ?項目??概要??構建步驟??清除步驟 ?Code&#x1f526;untitled…

【EasyX】快速入門——消息處理,音頻

1.消息處理 我們先看看什么是消息 1.1.獲取消息 想要獲取消息,就必須學會getmessage函數 1.1.1.getmessage函數 有兩個重載版本,它們的作用是一樣的 參數filter可以篩選我們需要的消息類型 我們看看參數filter的取值 當然我們可以使用位運算組合這些值 例如,我們…

華為CE6851-48S6Q-HI升級設備版本及補丁

文章目錄 升級前準備工作筆記本和交換機設備配置互聯地址啟用FTP設備訪問FTP設備升級系統版本及補丁 升級前準備工作 使用MobaXterm遠程工具連接設備&#xff0c;并作為FTP服務器準備升級所需的版本文件及補丁文件 筆記本和交換機設備配置互聯地址 在交換機接口配置IP&#…

Facebook隱私保護:數據安全的前沿挑戰

在數字化時代&#xff0c;隨著社交媒體的普及和應用&#xff0c;個人數據的隱私保護問題日益受到關注。作為全球最大的社交平臺之一&#xff0c;Facebook承載了數十億用戶的社交活動和信息交流&#xff0c;但與此同時&#xff0c;也面臨著來自內外部的數據安全挑戰。本文將深入…

AWS Elastic Beanstalk 監控可觀測最佳實踐

一、概述 Amazon Web Services (AWS) 包含一百多種服務&#xff0c;每項服務都針對一個功能領域。服務的多樣性可讓您靈活地管理 AWS 基礎設施&#xff0c;然而&#xff0c;判斷應使用哪些服務以及如何進行預配置可能會非常困難。借助 Elastic Beanstalk&#xff0c;可以在 AW…

【LinuxC語言】一切皆文件的理念

文章目錄 引言一、什么是“一切皆文件”&#xff1f;1. 文件柜的類比2. 統一的操作方式3. 舉個具體例子4. 設備文件5. 進程和網絡連接6. 簡化管理 二、這一設計的優勢1. 統一接口2. 靈活性3. 簡化了系統管理4. 增強了系統安全性 結論 引言 Linux 操作系統以其獨特的設計理念和…

如何使用JMeter 進行全鏈路壓測

使用 JMeter 進行全鏈路壓測&#xff1a;詳細步驟指南 全鏈路壓測旨在測試整個系統的性能&#xff0c;包括所有的組件和服務。通過 Apache JMeter 進行全鏈路壓測&#xff0c;可以模擬真實用戶行為&#xff0c;測試系統在高負載下的表現。以下是詳細的步驟指南&#xff0c;分為…

AWTK實現汽車儀表Cluster/DashBoard嵌入式GUI開發(七):快啟

前言: 汽車儀表是人們了解汽車狀況的窗口,而儀表中的大部分信息都是以指示燈形式顯示給駕駛者。儀表指示燈圖案都較為抽象,對駕駛不熟悉的人在理解儀表指示燈含義方面存在不同程度的困難,尤其對于駕駛新手,如果對指示燈的含義不求甚解,有可能影響駕駛的安全性。即使是對…

Pytest框架實戰二

在Pytest框架實戰一中詳細地介紹了Pytest測試框架在參數化以及Fixture函數在API測試領域的實戰案例以及具體的應用。本文章接著上個文章的內容繼續闡述Pytest測試框架優秀的特性以及在自動化測試領域的實戰。 conftest.py 在上一篇文章中闡述到Fixture函數的特性&#xff0c;第…

shell循環

一、for循環 用法&#xff1a; for 變量 in 取值列表 do 命令序列 done 例1&#xff1a;打印1到10的數字列表 #!/bin/bashfor i in {1..10} do echo $i done 例2&#xff1a;#批量添加用戶,用戶名存放在users.txt文件中&#xff0c;每行一個,初始密碼均設為123456 #!/bin/bas…

KMP算法【C++】

KMP算法測試 KMP 算法詳解 根據解釋寫出對應的C代碼進行測試&#xff0c;也可以再整理成一個函數 #include <iostream> #include <vector>class KMP { private:std::string m_pat;//被匹配的字符串std::vector<std::vector<int>> m_dp;//狀態二維數組…

怎樣解決Redis高并發競爭Key難點?

Redis作為一種高性能的鍵值存儲系統&#xff0c;在現代分布式系統中發揮著重要作用。然而&#xff0c;高并發場景下對同一Key的操作可能引發競爭條件&#xff0c;給系統穩定性和數據一致性帶來挑戰。本文將探討如何解決這一問題&#xff0c;為讀者提供有效的應對策略。 1. Red…

【002】FlexBison實現原理

0. 前言 Flex和Bison是用于構建處理結構化輸入的程序的工具。它們最初是用于構建編譯器的工具&#xff0c;但它們已被證明在許多其他領域都很有用。 &#xfeff; 在第一章中&#xff0c;我們將首先看一點(但不是太多)它們背后的理論&#xff0c;然后我們將深入研究一些使用它…

Mysql和Postgresql創建用戶和授權命令

Mysql和Postgresql創建用戶和授權命令 MySQL/MariaDB/TiDB mysql -uroot -P3306 -p 輸入密碼&#xff1a;xxx create user user1% identified by xxx; grant all privileges on *.* to user1%; create user user2% identified by xxx; grant all privileges on *.* to user2%;…

Winform /C# 截圖當前窗體,指定區域,當前屏幕

1.當前窗體 public static Image CaptureControl(Control ctrl){System.Drawing.Bitmap bmp new System.Drawing.Bitmap(ctrl.Width, ctrl.Height);ctrl.DrawToBitmap(bmp, new Rectangle(0, 0, ctrl.Width, ctrl.Height));return bmp;}private void DownLoad(){string filePa…

java類中運行main方法時報錯:找不到或無法加載主類 XXX

運行main類報了這個錯 錯誤: 找不到或無法加載主類 XXX 經過好一番查證才找出了問題所在 原因是 maven項目的provided導致的&#xff0c;現在記錄一下。 將pom.xml中標注provided的注釋掉&#xff0c;就不報錯了。

ERROR [internal] load metadata for docker.io/library/node:20-alpine

docker編譯時報錯&#xff0c;除標題外&#xff0c;還報如下信息 ERROR: failed to solve: node:20-alpine: failed to resolve source metadata for docker.io/library/node:20-alpine: failed to do request: Head "https://registry-1.docker.io/v2/library/node/mani…

常用個人信息

目錄 常用聯系方式我的自動思維常用媒體專業相關康米相關黑歷史 常用聯系方式 QQ&#xff1a;2868679921 微信&#xff1a;Commieee 郵箱&#xff1a;sharvefoxmail.com 我的自動思維 常用媒體 嗶哩嗶哩 專業相關 博客 康米相關 QQ&#xff1a;1203361015 黑歷史 貼吧…

PyQt5學習系列之QMetaObject.connectSlotsByName

文章目錄 前言一、pandas是什么&#xff1f;二、使用步驟 1.引入庫2.讀入數據總結 學習記錄 QMetaObject.connectSlotsByName——自動將信號連接到槽&#xff08;函數&#xff09; 例如&#xff1a; from PyQt5.QtWidgets import QMainWindow, QPushButton from PyQt5.QtCore…

哪些類型的產品適合用3D形式展示?

隨著3D技術的蓬勃發展&#xff0c;眾多品牌和企業紛紛投身3D數字化浪潮&#xff0c;將產品打造成逼真的3D模型進行展示&#xff0c;消費者可以更加直觀地了解產品的特點和優勢&#xff0c;從而做出更明智的購買決策。 哪些產品適合3D交互展示&#xff1f; 產品3D交互展示具有直…