LeetCode 01背包 494. 目標和

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


題解

首先對題目進行分析
所有的數字都要選,我們能做的是決定數字前面的符號,也就是這個數字是 + 還是 -
那么不妨將最后的結果視為 p - a,p為正數之和,a為負數之和,我們能夠通過選擇數字決定 p 是多少
又因為 p - a = target,a = sum(所有數的絕對值之和)- p,所以 p = (target + sum)/2
題目就變成從數組 nums 中選擇數字使其和為 (target + sum)/2 (不能重復選擇) ,這樣就是01背包問題

由于 p 是非負整數,所以如果target + sum是奇數或者負數,那么答案肯定是 0

定義 arr[ i ][ j ] 為選擇前 i 個數使其和為 j 的方法數
那么對于任意 arr[ i ][ j ] ,只有選擇 nums[ i-1 ] 和不選擇兩種可能
如果 nums[ i-1 ]>j,只能不選,arr[ i ][ j ]=arr[ i-1 ][ j ]
否則,arr[ i ][ j ]=arr[ i-1 ][ j ] + arr[ i-1 ][ j-nums[ i-1] ]
初始化 arr[0][0]=1,其余arr[0][j]為0
按順序遍歷數組即可


代碼如下↓

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {// p p是我們選擇的正數// s-p s是所有正數的和// 2p-s=target// p=(target+s)/2// 那么就是選擇數使其和為 p 即可int n=nums.size();int s=0;for(int i=0;i<n;i++){s+=nums[i];}if((target+s)%2 || target+s<0){return 0;}int p=(target+s)/2;vector<vector<int>> arr(n+1,vector<int>(p+1,0));arr[0][0]=1;for(int i=1;i<=n;i++){for(int j=0;j<=p;j++){arr[i][j]=arr[i-1][j];if(nums[i-1]<=j){arr[i][j]+=arr[i-1][j-nums[i-1]];}}}return arr[n][p];}
};

優化空間

二維滾動數組

我們發現 arr[ i ][ j ]=arr[ i-1 ][ j ] + arr[ i-1 ][ j-nums[ i-1] ] 或 arr[ i ][ j ]=arr[ i-1 ][ j ]
arr[ i ][ j ] 僅與上一行的 arr 有關,那我們不妨將二維數組縮減至兩行,一行存 i-1 ,一行存 i
在執行過程中進行滾動,將 i 和 i-1變為 i%2 和 (i-1)%2,從而優化空間


代碼如下↓

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {// p p是我們選擇的正數// s-p s是所有正數的和// 2p-s=target// p=(target+s)/2// 那么就是選擇數使其和為 p 即可int n=nums.size();int s=0;for(int i=0;i<n;i++){s+=nums[i];}if((target+s)%2 || target+s<0){return 0;}int p=(target+s)/2;vector<vector<int>> arr(2,vector<int>(p+1,0));arr[0][0]=1;for(int i=1;i<=n;i++){for(int j=0;j<=p;j++){arr[i%2][j]=arr[(i-1)%2][j];if(nums[i-1]<=j){arr[i%2][j]+=arr[(i-1)%2][j-nums[i-1]];}}}return arr[n%2][p];}
};

一維數組

類似的,既然arr[ i ][ j ] 僅與上一行的 arr 有關,一行,我們能否用一位數組表示

arr[ j ] = arr[ j ] + arr[ j-nums[ i-1 ] ](前面的arr[ j ]是arr[ i ][ j ],后面的都是arr[ i-1 ][ j ],上一行的)

同時,我們發現 arr[ j+1 ] 與其上一行的前面的數據有關
如果我們從前往后進行遍歷,那么后面的 arr[ j+1 ] 需要的 arr[ j ] 的數據就被新計算出來的 arr[ j+1 ] 給覆蓋了
所以我們需要從后向前遍歷,這樣就不會發生需要的數據被覆蓋的問題了


代碼如下↓

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {// p p是我們選擇的正數// s-p s是所有正數的和// 2p-s=target// p=(target+s)/2// 那么就是選擇數使其和為 p 即可int n=nums.size();int s=0;for(int i=0;i<n;i++){s+=nums[i];}if((target+s)%2 || target+s<0){return 0;}int p=(target+s)/2;vector<int> arr(p+1);arr[0]=1;for(int i=1;i<=n;i++){for(int j=p;j>=0;j--){if(nums[i-1]<=j){arr[j]+=arr[j-nums[i-1]];}}}return arr[p];}
};

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

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

相關文章

Dify 1.8.0 全網首發,預告發布

距離Dify 1.7.2過去兩周了 Dify 1.8.0 又跟大伙見面了&#xff01; 1.8.0&#xff0c;屬于主版本號不變、但第二位數字更新的“階段性大更”&#xff0c;意味著功能上的顯著優化和體驗上的重要升級。 根據官方的Github日志&#xff0c;這一版本將繼續聚焦三大核心方向&#x…

基于LangChain框架搭建AI問答系統(附源碼)

AI問答系統1. 背景知識2. 問答系統流程3. 知識問答系統相關組件3.1 文檔加載器3.2 文檔切割器3.3 嵌入模型包裝器3.4 向量存儲庫3.5 模型包裝器3.6 鏈組件4. 問答系統演示4.1 問答程序4.2 演示大模型回答效果5.問答系統代碼1. 背景知識 在人工智能技術飛速發展的今天&#xff…

【Python】QT(PySide2、PyQt5):Qt Designer,VS Code使用designer,可能的報錯

Qt designer&#xff1a;可直接在designer界面&#xff0c;使用拖拽的方式設計需要的界面&#xff0c;可設定部分屬性。安裝Pyside2后&#xff0c;designer默認在python安裝目錄的Lib/sit_packages/PySide2文件夾中。designer使用&#xff1a;① 雙擊打開designer.exe&#xff…

前端常見安全問題 + 防御方法 + 面試回答

目錄 XSS&#xff08;跨站腳本攻擊&#xff09;CSRF&#xff08;跨站請求偽造&#xff09;SQL 注入文件上傳漏洞其他前端常見安全問題面試常見問答 1. XSS&#xff08;跨站腳本攻擊&#xff09; 定義 XSS&#xff08;Cross-Site Scripting&#xff09;是一種 通過注入惡意腳…

jxWebUI--下拉選擇框

下拉選擇框提供了預先定義好的選項&#xff0c;用戶只能在這些選項中選擇輸入。 combobox 定義格式 combobox 控件名 屬性列表 ;屬性 bind 類型&#xff1a;string 缺省值&#xff1a; 輸入控件所綁定的變量名。當給輸入控件bind了一個變量名后【bindbind_var_name】&#xff0…

大模型時代:用Redis構建百億級向量數據庫方

大模型時代&#xff1a;用Redis構建百億級向量數據庫方案第一章&#xff1a;大模型時代的向量數據庫挑戰1.1 大模型時代的特征與需求1.2 向量數據庫的核心價值1.3 百億級向量的技術挑戰第二章&#xff1a;Redis作為向量數據庫的優勢2.1 Redis的核心優勢2.2 Redis向量搜索模塊&a…

jsqlparser(六):TablesNamesFinder 深度解析與 SQL 格式化實現

在數據庫應用開發中&#xff0c;SQL語句的解析和處理是一項常見而重要的任務。本文將深入探討 JSQLParser 中的 TablesNamesFinder 類&#xff0c;分析其核心原理、與 AST 訪問接口&#xff08;CCJSqlParserVisitor &#xff09;的關系、使用場景&#xff0c;并通過實際代碼示例…

Python訓練營打卡Day49-神經網絡調參指南

知識點回顧&#xff1a;隨機種子內參的初始化神經網絡調參指南 參數的分類調參的順序各部分參數的調整心得 作業&#xff1a;對于day41的簡單cnn&#xff0c;看看是否可以借助調參指南進一步提高精度。 隨機種子 import torch import torch.nn as nn# 定義簡單的線性模型&…

Elasticsearch 常用任務管理命令及實戰應用

常用任務管理命令 列出所有任務 curl -X GET "http://<es_host>:<es_port>/_tasks?detailedtrue&pretty" -H Content-Type: application/json獲取特定類型的任務 curl -X GET "http://<es_host>:<es_port>/_tasks?actions<act…

Java試題-選擇題(26)

Java試題-選擇題(26) 題目 下列有關Thread的描述,哪個是正確的 ? A:啟動一個線程的方法是:thread. run() B:結束一個線程的通常做法是:thread. stop() C:將一個線程標記成daemon線程,意味著當主線程結束,并且沒有其它正在運行的非daemon線程時,該daemon線程也會自…

緩存的原理、引入及設計

開篇寄語&#xff1a;緩存&#xff0c;你真的用對了嗎&#xff1f; 我們為什么要學習緩存呢&#xff1f;有必要學習緩存嗎&#xff1f; 緩存的使用&#xff0c;是提升系統性能、改善用戶體驗的唯一解決之道。 其實&#xff0c;作為互聯網公司&#xff0c;只要有直接面對用戶的業…

單片機如何控制模數轉換芯片

一、介紹單片機控制模數轉換&#xff08;ADC&#xff09;芯片的核心是通過通信接口發送控制指令&#xff0c;并讀取轉換后的數字信號&#xff0c;本質是“指令交互數據傳輸”的協同過程&#xff0c;具體實現需分4步完成&#xff0c;關鍵在于接口匹配和時序同步。二、核心1. 先明…

【Proteus仿真】開關控制系列仿真——開關控制LED/撥碼開關二進制計數/開關和繼電器控制燈滅

目錄 0案例視頻效果展示 0.1例子1&#xff1a;開關控制LED燈亮滅 0.2例子2&#xff1a;數碼管顯示撥碼開關二進制計數(000~255) 0.3例子3&#xff1a;開關和繼電器控制燈亮滅 1基礎知識補充 1.1 74LS245雙總線收發器 1.1.1 引腳及功能 1.1.2應用場景 1.1.3真值表 1.2…

Q1 Top IF 18.7 | 基于泛基因組揭示植物NLR進化

文章DOI: 10.1016/j.chom.2025.07.011 標題&#xff1a;Pangenomic context reveals the extent of intraspecific plant NLR evolution 期刊&#xff1a;Cell Hose & Microbe (https://i-blog.csdnimg.cn/direct/0e31f86b94d348b0a1adb084ec4e49b7.png)(https://i-blog.cs…

技術干貨|Prometheus PromQL查詢語言之聚合操作內置函數

聚合操作 Prometheus還提供了下列內置的聚合操作符,這些操作符作用域瞬時向量。可以將瞬時表達式返回的樣本數據進行聚合,形成一個新的時間序列。 sum (求和) min (最小值) max (最大值) avg (平均值) stddev (標準差) stdvar (標準差異) count (計數) count_values …

Redis 哨兵(Sentinel)全面解析

在2025年的數字化浪潮中&#xff0c;想象這樣一個場景&#xff1a;凌晨3點&#xff0c;電商平臺流量突然暴增&#xff0c;主Redis服務器因硬件故障突然宕機。幾年前&#xff0c;這意味著緊急電話、慌亂的運維人員和不可避免的業務中斷。而今天&#xff0c;用戶甚至沒有察覺任何…

【數學史冷知識】關于行列式的發展史

學習的途中會遇到一些有意思的東西&#xff0c;我想著做一個專欄《艾薩克紀行簡報》&#xff0c;專門寫這些知識發展歷史。可以讓您從繁忙的學習生活中放松&#xff0c;添些耀彩。行列式和微積分一樣&#xff0c;都是兩個人獨立發現的。而且還都有萊布尼茨。1683 年&#xff0c…

【python】python進階——生成器

目錄 一、生成器介紹 1.1 生成器與迭代器的關系 1.2 生成器與return比較 二、創建生成器 方法1: 生成器函數 方法2: 生成器表達式 三、生成器的實際應用場景 3.1 處理大型文件 3.2 生成無限序列 3.3 數據管道處理 四、生成器的高級用法 4.1 使用send()方法傳遞值 …

【Pytorch】生成對抗網絡實戰

GAN框架基于兩個模型的競爭&#xff0c;Generator生成器和Discriminator鑒別器。生成器生成假圖像&#xff0c;鑒別器則嘗試從假圖像中識別真實的圖像。作為這種競爭的結果&#xff0c;生成器將生成更好看的假圖像&#xff0c;而鑒別器將更好地識別它們。 目錄 創建數據集 定…

Java基礎第7天總結(代碼塊、內部類、函數式編程)

代碼塊靜態代碼塊&#xff1a;有static修飾&#xff0c;屬于類&#xff0c;與類一起優先加載&#xff0c;自動執行一次實例代碼塊&#xff1a;無static修飾&#xff0c;屬于對象&#xff0c;每次創建對象時&#xff0c;都會優先執行一次。package com.itheima.code;import java…