leedcode 算法刷題第三十一天

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

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

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

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

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

示例 1:

輸入:stones = [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],這就是最優值。

示例 2:

輸入:stones = [31,26,33,21,40]
輸出:5

提示:

  • 1 <= stones.length <= 30
  • 1 <= stones[i] <= 100
class Solution {
public:int lastStoneWeightII(vector<int>& stones) {vector<int> dp(150001,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];}
};

解題思路:

問題背景

問題描述:有一堆石頭,每次從中挑選兩塊石頭碰撞,碰撞后會得到一塊新石頭(重量為兩塊石頭的差值),直到只剩下一塊石頭或沒有石頭。求最后可能剩下的最小石頭重量。

核心思路轉化

這個問題可以轉化為:

  • 將石頭分成兩堆,使兩堆的重量盡可能接近
  • 兩堆重量的差值就是最后可能剩下的最小重量

這是因為每次碰撞相當于從總重量中減去 twice of 較小的那塊石頭的重量,最優策略是讓兩堆石頭重量盡可能接近。

代碼原理詳解

  1. 動態規劃數組定義
    dp[j]表示能從石頭中選出若干塊,使得它們的總重量最大為j

  2. 計算目標值
    sum是所有石頭的總重量
    targetsum/2,我們嘗試找到不超過這個值的最大子集和

  3. 0-1 背包問題求解

    • 外層循環遍歷每塊石頭(物品)
    • 內層循環從target往當前石頭重量遍歷(0-1 背包的典型做法,避免重復使用同一物品)
    • dp[j] = max(dp[j], dp[j - stones[i]] + stones[i])表示對于重量j,要么不選當前石頭保持dp[j],要么選當前石頭得到dp[j - stones[i]] + stones[i]
  4. 計算結果
    sum - dp[target] - dp[target]表示總重量減去兩倍的最大子集和(即兩堆石頭的重量差)

這個解法的時間復雜度是 O (n×target),空間復雜度是 O (target),其中 n 是石頭數量,target 是總重量的一半。

494. 目標和

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum = 0;for (int i = 0; i < nums.size(); i++) sum += nums[i];if (abs(target) > sum) return 0; // 此時沒有方案if ((target + sum) % 2 == 1) return 0; // 此時沒有方案int bagSize = (target + 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];}
};

給每個數字添加+-,本質上是將數組分成兩組:

  • 一組數字前面加+(和為left
  • 另一組數字前面加-(和為right

根據題意,我們有:

plaintext

left - right = target  // 表達式結果等于target
left + right = sum     // 所有數字的總和

將兩式相加可得:2*left = target + sum,即?left = (target + sum) / 2

因此問題轉化為:找到有多少種方法可以從數組中選出一些數字,使它們的和等于 left

代碼解析

  1. 邊界條件判斷

    if (abs(target) > sum) return 0; // 目標值的絕對值大于總和,不可能實現
    if ((target + sum) % 2 == 1) return 0; // 和為奇數,無法被2整除,沒有方案
    
  2. 計算背包大小

    int bagSize = (target + sum) / 2;
    
    ?

    這里的bagSize就是我們要找的left值,即需要選出和為bagSize的數字組合

  3. 動態規劃初始化

    ?
    vector<int> dp(bagSize + 1, 0);
    dp[0] = 1; // 表示湊出和為0的方法有1種(什么都不選)
    
    ?

    dp[j]的含義是:有多少種方法可以選出和為 j 的數字組合

  4. 填充 DP 數組

    ?
    for (int i = 0; i < nums.size(); i++) { // 遍歷每個數字for (int j = bagSize; j >= nums[i]; j--) { // 倒序遍歷背包dp[j] += dp[j - nums[i]];}
    }
    
    ?
    • 對于每個數字,我們可以選擇 "放入背包"(即該數字前面加+)或 "不放入背包"(即該數字前面加-
    • 狀態轉移方程dp[j] += dp[j - nums[i]]表示:湊出和為 j 的方法數 = 不選當前數字的方法數 + 選當前數字的方法數(此時需要加上湊出 j-nums [i] 的方法數)
    • 倒序遍歷是為了保證每個數字只被使用一次(0-1 背包特性)
  5. 返回結果

    return dp[bagSize];
    
    ?

    dp[bagSize]就是能湊出和為bagSize的方法總數,也就是我們要求的答案

示例說明

nums = [1,1,1,1,1]target = 3為例:

  • 總和sum = 5
  • bagSize = (3 + 5) / 2 = 4
  • 問題轉化為:有多少種方法從數組中選出和為 4 的數字
  • 答案是 5 種,對應 5 種不同的表達式

474. 一和零

class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {vector<vector<int>> result(m+1,vector<int> (n+1,0));for(string str:strs){int onenumber = 0,zeronumber = 0;for (char c : str) {if (c == '0') zeronumber++;else onenumber++;}for(int i=m;i>=zeronumber;i--){for(int j=n;j>=onenumber;j--){result[i][j] = max(result[i][j],result[i-zeronumber][j-onenumber]+1);}}}return result[m][n];}};

問題理解

給定一組二進制字符串,每個字符串包含0和1。我們需要選擇一些字符串,使得:

  • 所有選中字符串中0的總數不超過?m

  • 所有選中字符串中1的總數不超過?n

  • 選中的字符串數量盡可能多

動態規劃思路

1. 狀態定義

dp[i][j]?表示:使用最多?i?個0和?j?個1時,能夠組成的最大字符串數量

2. 狀態轉移

對于每個字符串,我們有兩種選擇:

  • 不選這個字符串dp[i][j]?保持不變

  • 選這個字符串dp[i][j] = dp[i - zeros][j - ones] + 1

狀態轉移方程:

cpp

dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1);

3. 為什么從后往前遍歷?

這是0-1背包問題的核心技巧:

  • 從后往前遍歷:確保每個字符串只被使用一次(避免重復選擇)

  • 如果從前往后遍歷,會變成完全背包問題(每個物品可以選多次)

4. 具體步驟

  1. 初始化:創建?(m+1) × (n+1)?的二維數組,初始值為0

  2. 遍歷每個字符串

    • 計算當前字符串的0和1的數量

    • 從?m?到?zeros,從?n?到?ones?反向更新dp表

  3. 返回結果dp[m][n]?就是最大數量

示例說明

假設?strs = ["10", "0001", "111001", "1", "0"],?m = 5,?n = 3

對于字符串 "10":

  • zeros = 1, ones = 1

  • 更新所有?i >= 1?且?j >= 1?的位置

對于字符串 "0001":

  • zeros = 3, ones = 1

  • 更新所有?i >= 3?且?j >= 1?的位置

以此類推...

時間復雜度

  • 外層循環:O(S),S為字符串數量

  • 內層循環:O(M × N)

  • 總復雜度:O(S × M × N)

空間復雜度

  • O(M × N),即dp表的大小

這種解法巧妙地利用了動態規劃和背包問題的思想,通過反向遍歷確保每個字符串只被考慮一次,從而找到最優解。

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

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

相關文章

圖神經網絡介紹

源自論文&#xff1a;Survey on Graph Neural Networks 圖神經網絡&#xff08;GNNs&#xff09;中的符號與定義詳解 本文使用了圖論和深度學習領域的標準符號體系&#xff0c;以確保對圖結構數據的描述清晰一致。以下是核心符號和定義的詳細說明&#xff1a; 一、基礎圖結構符…

測試報告:“問卷考試系統”項目

目錄 一、報告概述 &#xff08;一&#xff09;項目背景 &#xff08;二&#xff09;項目核心模塊與測試目的 1、項目核心模塊 2、測試目的 &#xff08;三&#xff09;測試環境 1、硬件環境 2、軟件環境 &#xff08;1&#xff09;操作系統 &#xff08;2&#xff0…

Linux筆記---網絡計算器

1. 網絡程序分層 我們說過&#xff0c;OSI7層模型十分完美&#xff0c;但是因特網實際上采用的是TCP/IP五層模型&#xff1a; 實際上&#xff0c;對比可以發現&#xff0c;TCP/IP模型實際上就是將OSI的前三層模型合并為了應用層。 這就提示我們&#xff0c;我們設計的應用程…

《智能網聯汽車交通仿真軟件可信度評估》團標啟動會圓滿舉辦

讓數據真正閉環的L4級自動駕駛仿真工具鏈&#xff0d;杭州千岑智能科技有限公司&#xff1a;RSim 近日&#xff0c;由中國仿真學會主辦、清華大學牽頭的《智能網聯汽車交通仿真軟件可信度評估》團體標準啟動會在北京成功舉行。杭州千岑科技有限公司作為智能網聯汽車測試驗證領域…

關于 MCU 芯片外圍電路的快速入門介紹

MCU&#xff08;微控制單元&#xff0c;Microcontroller Unit&#xff09;是嵌入式系統的“大腦”&#xff0c;但需通過外圍電路實現供電、信號輸入/ 輸出、通信、存儲等功能&#xff0c;才能構成完整的工作系統。外圍電路的設計直接決定 MCU 的穩定性、功能擴展性和適用場景&a…

Uniapp onLoad 和 onShow 區別

一、核心區別生命周期觸發時機執行次數參數獲取onLoad頁面首次創建時觸發僅1次支持獲取URL參數optionsonShow頁面每次顯示時觸發&#xff08;包括返回&#xff09;多次無法獲取URL參數二、實戰數據請求場景優先使用onLoad請求數據的場景&#xff1a;初始化數據當需要根據URL參數…

大模型預訓練評估指標

模型效果評測 關于 Language Modeling 的量化指標&#xff0c;較為普遍的有 [PPL]&#xff0c;[BPC]等,可以簡單理解為在生成結果和目標文本之間的 Cross Entropy Loss 上做了一些處理&#xff0c;這種方式可以用來評估模型對「語言模板」的擬合程度即給定一段話&#xff0c;預…

【Matlab】-- 機器學習項目 - 基于XGBoost算法的數據回歸預測

文章目錄 文章目錄01 內容概要02 部分代碼03 代碼解讀04 運行結果05 基于XGBoost算法的數據回歸預測源碼01 內容概要 XGBoost屬于集成學習中的Boosting方法&#xff0c;其基本思想是&#xff1a; 逐步構建多個弱學習器&#xff08;通常是CART決策樹&#xff09;&#xff0c;每…

Memory in LLM Agent

Memory in LLM Agent 1 為什么需要“記憶” —— 背景與動機 在構建 LLM Agent&#xff08;Large Language Model Agent&#xff0c;大語言模型驅動的智能體&#xff09;的過程中&#xff0c;“記憶”&#xff08;Memory&#xff09;是一個繞不開的核心問題。沒有記憶的 Agent…

三甲地市級醫院數據倉湖數智化建設路徑與編程工具選型研究(上)

摘要 本研究旨在探索三甲地市級醫院數據倉湖數智化建設的實施路徑與工具選型策略,以響應國家《"十四五"全民健康信息化規劃》中2025年醫療數據平臺聯通全覆蓋的政策要求,同時解決地市級醫院面臨的資源限制(年均信息化投入占總營收1.5%)、區域協同需求突出及多業…

25.9.10_CTF-reverse_RC4那些事兒

CTF-reverse_RC4那些事兒 0x00 RC4加密知識點 推薦看這位up主的視頻https://www.bilibili.com/video/BV1G64y1Y7p4/?spm_id_from333.1391.0.0&p2 簡單來說RC4算法包括兩部分KSA(利用Key生成S盒)和PRGA(利用S盒生成密鑰流): KSA: 初始化S&#xff08;一般是0-255&…

網絡編程(6)

【0】復習 Modbus&#xff1a;modbus tcp modbus rtu Modbus TCP: 特點&#xff1a;主從問答&#xff08;控制 采集信息&#xff09; 應用層協議&#xff08;基于TCP通信&#xff09;、默認端口502 組成&#xff1a;報文頭&#xff08;7 事物2 協議2 長度2 單元表示1&#xff…

技術文章大綱:AI繪畫—動漫角色生成賽

技術文章大綱&#xff1a;AI繪畫—動漫角色生成賽 背景與意義 動漫角色生成賽的興起與發展AI繪畫技術在動漫創作中的應用價值比賽對推動AI藝術創新的作用 技術核心&#xff1a;AI繪畫模型 主流模型介紹&#xff08;如Stable Diffusion、MidJourney、DALLE&#xff09;針對動…

Flink-新增 Kafka source 引發狀態丟失導致啟動失敗

背景 Flink Job 新增 kafka source 算子,從狀態保留并啟動后提示 org.apache.flink.util.StateMigrationException: The new state typeSerializer for operator state must not be incompatible,導致任務 Fail。 Source: task-kafka-source -> task-kafka-transform (1…

【系統架構設計(26)】系統可靠性分析與設計詳解:構建高可用軟件系統的核心技術

文章目錄一、本文知識覆蓋范圍1、概述2、知識體系概覽二、系統可靠性基礎概念1、可靠性與可用性的本質區別2、軟件可靠性與硬件可靠性的深度對比3、核心可靠性指標的業務價值三、系統架構可靠性模型1、串聯系統的可靠性挑戰2、并聯系統的高可靠性設計3、混合系統的復雜性管理四…

4 C 語言數據結構實戰:棧和隊列完整實現(結構體 + 函數)+ 最小棧解決方案

棧和隊列 1. 棧 棧&#xff1a;?種特殊的線性表&#xff0c;其只允許在固定的?端進?插?和刪除元素操作。進?數據插?和刪除操作 的?端稱為棧頂&#xff0c;另?端稱為棧底。棧中的數據元素遵守后進先出LIFO&#xff08;Last In First Out&#xff09;的原則。 壓棧&…

Milvus基于docker主機外掛實踐

一、安裝docker與我之前寫的原博客&#xff1a;ubuntu安裝milvus向量數據庫&#xff0c;獲取key不同&#xff0c;原博客獲取key已經過時# 更新Ubuntu軟件包列表和已安裝軟件的版本: sudo apt update# 安裝Ubuntu系統的依賴包 sudo apt-get install ca-certificates curl gnupg …

使用python test測試http接口

使用python test測試http接口獲取token和控制session&#xff0c;后面大多數接口要帶上這些信息 import time import requestsfrom common.aes_algorithm import AES from config.config import Config from config.log import logclass Common:username "admin"pas…

平時只會CRUD,沒有高質量項目經驗,我該怎么辦

我沒有項目經驗怎么辦 首先&#xff0c;不管是應屆生還是社招幾年工作經驗的朋友&#xff0c;除非特別厲害的人&#xff0c;大家都會遇到這個問題。 我們該怎么處理&#xff0c;關注hikktn&#xff01;為你解答這個問題。 問AI世面上那個大廠程序員項目推薦 為什么這么說呢&…

網編.hw.9.10

云盤下載#include <myhead.h> #define SER_IP "192.168.108.93" #define SER_PORT 69 #define addr "192.168.109.6" #define port 8888/******************主程序******************/ int main(int argc, const char *argv[]) {//1、創建一個用于通…