Day36--動態規劃--1049. 最后一塊石頭的重量 II,494. 目標和,474. 一和零

Day36–動態規劃–1049. 最后一塊石頭的重量 II,494. 目標和,474. 一和零

遇到難題,思考超過20分鐘沒有思路的,要跳過!不然時間效率太低了。

**看題解同理,看20分鐘看不懂的,也要跳過!**做同類型的題目,過幾天回頭再看,可能會豁然開朗。

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

思路:

動態規劃

  1. 總體上來說,就是找兩塊最接近的石頭碰撞,拓展出來,就是找兩組最接近的石頭碰撞。——就是找兩個和最接近的子集。
  2. 到這里就和上一題《416. 分割等和子集》差不多了。
  3. 因為sum/2是向下取整,所以half肯定是<=sum的半值的。
  4. 就算sum是偶數,half恰好是sum的一半,也不能保證剛好就有石頭能累加和得到half。因為碰撞完剩余的石頭不一定是0。所以我們求的dp[half]肯定是小于等于half的。
  5. 所以我們求的dp[half],是重量小的那一組。剩余的半組石頭是重量大的sum-dp[half]。將二者碰撞,相減,就得到答案。

對這個過程不理解的話,一定要把sum,half,dp[]數組的全過程,給打印出來,看懂。

class Solution {public int lastStoneWeightII(int[] stones) {int n = stones.length;// 使用stream快速求和int sum = Arrays.stream(stones).sum();int half = sum / 2;// // 檢查sum和half數值// System.out.println("sum = " + sum);// System.out.println("half = " + half);// 背包的容量是halfint[] dp = new int[half + 1];// 遍歷for (int i = 0; i < n; i++) {// 倒序遍歷for (int j = half; j >= stones[i]; j--) {dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);}// // 遍歷檢查dp[]數組// for (int j = 0; j <= half; j++) {//     System.out.print(dp[j] + " ");// }// System.out.println(" ");}return sum - dp[half] - dp[half];}
}

簡潔版代碼:

class Solution {public int lastStoneWeightII(int[] stones) {int n = stones.length;int sum = Arrays.stream(stones).sum();int half = sum / 2;int[] dp = new int[half + 1];for (int i = 0; i < n; i++) {for (int j = half; j >= stones[i]; j--) {dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);}}return sum - dp[half] - dp[half];}
}

494. 目標和

方法:回溯

思路:

class Solution {int count = 0;public int findTargetSumWays(int[] nums, int target) {backtracking(nums, target, 0, 0);return count;}public void backtracking(int[] nums, int target, int index, int sum) {if (index == nums.length) {if (sum == target) {count++;}} else {backtracking(nums, target, index + 1, sum + nums[index]);backtracking(nums, target, index + 1, sum - nums[index]);}}
}

方法:動態規劃

思路:

題目分析:

假設要加’+‘號的元素有pos個,要加’-'的元素設為neg,就是sum-pos個

因為pos - neg = target,等同于pos - (sum-pos) = target

可以得出 pos = (sum + target) / 2

此時我們可以求,最多有多少種方法,可以裝滿容量為pos的背包

動態規劃分析:

  1. 確定dp[j]的含義:有dp[j]種方法填滿容量為j的包
  2. 確定遞推公式:
    1. 情況一:不放nums[i],就直接是“上一層”的dp[j],以為這是滾動數組,所以直接等于
    2. 情況二:放num[i],就看上一層[j - nums[i]]的位置有多少種方法(因為這里不是求最大值,所以不用+value[i])
    3. 因為這里求的是“最多有多少種方法”,所以并不是取max,而是把情況一和情況二求和
    4. 公式:dp[j] = dp[j] + dp[j - nums[i]];
  3. 初始化,dp[0] = 1。
class Solution {public int findTargetSumWays(int[] nums, int target) {int sum = Arrays.stream(nums).sum();//如果target的絕對值大于sum,那么是沒有方案的if (Math.abs(target) > sum) {return 0;}//如果(target+sum)除以2的余數不為0,也是沒有方案的if ((target + sum) % 2 == 1) {return 0;}int pos = (target + sum) / 2;int[] dp = new int[pos + 1];dp[0] = 1;for (int i = 0; i < nums.length; i++) {for (int j = pos; j >= nums[i]; j--) {// 情況一:不放nums[i],就直接是“上一層”的dp[j],以為這是滾動數組,所以直接等于// 情況二:放num[i],就看上一層[j - nums[i]]的位置有多少種方法(因為這里不是求最大值,所以不用+value[i])// 因為這里求的是“最多有多少種方法”,所以并不是取max,而是把情況一和情況二求和dp[j] = dp[j] + dp[j - nums[i]];}// // 遍歷檢查dp[]數組// for (int j = 0; j <= pos; j++) {//     System.out.print(dp[j] + " ");// }// System.out.println(" ");}return dp[pos];}
}

簡潔版代碼:

class Solution {public int findTargetSumWays(int[] nums, int target) {int sum = Arrays.stream(nums).sum();if (Math.abs(target) > sum) {return 0;}if ((target + sum) % 2 == 1) {return 0;}int pos = (target + sum) / 2;int[] dp = new int[pos + 1];dp[0] = 1;for (int i = 0; i < nums.length; i++) {for (int j = pos; j >= nums[i]; j--) {dp[j] = dp[j] + dp[j - nums[i]];}}return dp[pos];}
}

474. 一和零

思路:

注意本題雖然是二維數組,但是依然是滾動數組。因為維度多了一個,要記錄0和1的情況。

  1. dp數組定義:dp[i][j]表示i個0和j個1時的最大子集
  2. dp遞推公式:dp[i][j] = Math.max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
  3. 初始化:全部為0就可以
  4. 遞歸順序:因為是滾動數組,i和j都要倒序遍歷
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);}}// // 遍歷檢查dp[]數組// for (int i = 0; i <= m; i++) {//     for (int j = 0; j <= n; j++) {//         System.out.print(dp[i][j] + " ");//     }//     System.out.print(" ");// }}return dp[m][n];}
}

這題增加多了一個維度之后,更加燒腦了。建議把dp數組打印出來,自己對著代碼推一遍。加深了理解。

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

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

相關文章

前端開發技術深度總結報告

前端開發技術深度總結報告 &#x1f4cb; 項目背景 基于 Vue 3 TypeScript Element Plus 的企業級產品管理系統&#xff0c;重點解決產品表單的數據緩存、頁面導航、用戶體驗等核心問題。&#xfffd;&#xfffd; 遇到的問題及解決方案 1. 瀏覽器控制臺錯誤處理 問題: 大量第…

Linux 單機部署 Kafka 詳細教程(CentOS 7+)

系列博客專欄&#xff1a; SpringBoot與微服務實踐系列博客Java互聯網高級培訓教程 一、環境準備 1. 操作系統要求 Kafka 可以在多種 Linux 發行版上運行&#xff0c;本文以 CentOS 7 為例&#xff0c;其他發行版步驟類似&#xff0c;只需調整包管理命令。 2. Java 環境要…

解析工業機器視覺中的飛拍技術

在工業機器視覺的領域&#xff0c;"飛拍"這個術語時常被提起&#xff0c;尤其是在高速檢測和動態捕捉的場景中。但你真的了解飛拍是什么嗎&#xff1f;它到底如何工作&#xff0c;能為工業應用帶來哪些突破性改進呢&#xff1f;讓我們一起來解密。1. 飛拍的核心概念 …

[特殊字符]企業游學 | 探秘字節,解鎖AI科技新密碼

寶子們&#xff0c;想知道全球科技巨頭字節跳動的成功秘籍嗎&#xff1f;一場企業游學&#xff0c;帶你深入字節跳動創新基地&#xff0c;探索AI新科技&#xff0c;揭開規模化增長背后的神秘面紗?字節跳動&#xff1a;全球經濟價值的創造者字節跳動可太牛啦&#xff01;TikTok…

主流大數據框架深度解析:從介紹到選型實戰

主流大數據框架深度解析:從介紹到選型實戰 在數據驅動的時代,選擇合適的大數據處理框架是構建高效、可靠數據平臺的關鍵。 深入剖析 Hadoop MapReduce、Apache Spark、Apache Flink 和 Kafka Streams 四大主流框架,從框架介紹、具體使用場景、優缺點、選擇建議到實際案例,…

座艙HMI軟件開發架構:核心功能與案例解析

隨著智能座艙的持續演進&#xff0c;HMI&#xff08;Human Machine Interface&#xff0c;人與機器交互界面&#xff09;系統已從單一的顯示控制器演變為集多屏聯動、多模態交互、車載服務集成于一體的智能系統&#xff0c;需要一個多系統、多設備協同運行的復雜架構來支撐。本…

把“思考”塞進 1 KB:我用純 C 語言給單片機手搓了一個微型 Transformer 推理引擎

標簽&#xff1a;TinyML、Transformer、單片機、Cortex-M、量化、KV-Cache、裸機編程 ---- 1. 為什么要在 64 KB SRAM 的 MCU 上跑 Transformer&#xff1f; 2024 年以前&#xff0c;TinyML ≈ CNN CMSIS-NN&#xff0c;做語音喚醒或簡單分類就到頭了。 但產品同事突然拍腦袋&…

什么是CLI?

什么是CLI&#xff1f;CLI&#xff08;Command Line Interface&#xff09;是命令行界面的縮寫&#xff0c;是一種通過文本命令與計算機程序交互的方式。通俗比喻CLI就像是一個"智能助手"&#xff1a;你輸入命令&#xff0c;它執行任務就像和機器人對話一樣&#xff…

mysql基本sql語句大全

十分想念順店雜可。。。以下是 MySQL 中常用的基本 SQL 語句大全&#xff0c;按功能分類整理&#xff0c;包含語法和示例&#xff0c;方便參考使用&#xff1a;一、數據庫操作&#xff08;DDL&#xff09;用于創建、刪除、切換數據庫。創建數據庫-- 基本語法 CREATE DATABASE […

構建響應式在線客服聊天系統的前端實踐 Vue3+ElementUI + CSS3

構建響應式客服聊天系統的前端實踐在當今數字化時代&#xff0c;客服系統已成為企業與客戶溝通的重要橋梁。一個優秀的在線客服系統不僅需要功能完善&#xff0c;還需要在各種設備上都能提供良好的用戶體驗。本文將介紹如何構建一個響應式的客服聊天界面&#xff0c;確保在桌面…

C語言memcpy函數詳解:高效內存復制的實用工具

目錄1. memcpy函數是什么&#xff1f;函數原型2. memcpy函數的用法運行結果&#xff1a;代碼解析3. memcpy函數的注意事項3.1 內存區域不重疊3.2 緩沖區大小管理3.3 指針有效性3.4 性能優勢3.5 平臺兼容性4. 實際應用場景4.1 數組復制4.2 動態內存復制4.3 結構體復制4.4 緩沖區…

多級緩存架構:新品咖啡上線引發的數據庫壓力風暴與高并發實戰化解方案

一、背景&#xff1a;新品咖啡風暴與數據庫之痛想象一下&#xff1a;某知名咖啡品牌推出限量版“星空冷萃”&#xff0c;通過社交媒體引爆流量。上午10點開售瞬間&#xff0c;APP與網站涌入數十萬用戶&#xff0c;商品詳情頁、庫存查詢請求如海嘯般涌向后臺。傳統架構下&#x…

888. 公平的糖果交換

目錄 題目鏈接&#xff1a; 題目&#xff1a; 解題思路&#xff1a; 代碼&#xff1a; 總結&#xff1a; 題目鏈接&#xff1a; 888. 公平的糖果交換 - 力扣&#xff08;LeetCode&#xff09; 題目&#xff1a; 解題思路&#xff1a; 前一個數組和sumA,后一個數組sumB,然…

Day01 項目概述,環境搭建

軟件開發整體介紹 軟件開發流程 需求分析&#xff1a;需求規格說明書、產品原型 設計&#xff1a;UI 設計、數據庫設計&#xff0c;接口設計 編碼&#xff1a;項目代碼、單元測試 測試&#xff1a;測試用例、測試報告 上線運維&#xff1a;軟件環境安裝、配置 角色分工 項…

Perl Socket 編程

Perl Socket 編程 引言 Perl 語言作為一種強大的腳本語言,在系統管理和網絡編程領域有著廣泛的應用。Socket 編程是網絡編程的核心,它允許程序在網絡中進行數據傳輸。本文將詳細介紹 Perl 語言中的 Socket 編程,包括 Socket 的概念、創建、通信以及一些高級應用。 Socket…

3 種簡單方法備份 iPhone 上的短信 [2025]

短信通常承載著我們工作和私人生活中有價值的信息和美好的回憶&#xff0c;以及我們不想丟失的特別對話。這就是為什么備份 iPhone 短信如此重要的原因。如果出現問題&#xff0c;比如意外刪除或系統問題&#xff0c;備份意味著你可以輕松地恢復短信。在本指南中&#xff0c;我…

Linux庫路徑三劍客:/usr/lib、/usr/local/lib、~/.local/lib 詳解與避坑指南

在Linux的世界里&#xff0c;/usr/lib、/usr/local/lib和~/.local/lib這三個路徑看似只是簡單的文件夾&#xff0c;實則是軟件包管理和開發環境的基石。理解它們的區別&#xff0c;不僅能讓你的pip install、make install等命令得心應手&#xff0c;更能避免ImportError、comma…

python 之 autogen-core《二》代理運行環境、應用程序堆棧、代理生命周期

支持兩種類型的運行時環境&#xff1a;獨立式和分布式 獨立代理運行時 獨立運行時適用于單進程應用程序&#xff0c;其中所有代理均使用同一種編程語言實現并在同一進程中運行。在 Python API 中&#xff0c;獨立運行時的一個示例是SingleThreadedAgentRuntime。 在這里&…

歐姆龍PLC CP1H在視覺檢測產線中的應用:以太網模塊實現上位機實時采樣與觸摸屏報警聯動

一、行業痛點與解決方案概述以某汽車零部件制造企業的生產線檢測系統為例&#xff0c;該企業原本使用歐姆龍CP1H PLC作為主控制器。由于CP1H PLC本身不具備以太網接口&#xff0c;只能通過串口&#xff08;如RS232或RS485&#xff09;進行通訊。這種通訊方式存在傳輸距離短、傳…

快速找到兩個 Word 文檔之間文字的區別

要快速找到兩個 Word 文檔之間文字的區別&#xff0c;可以使用 Microsoft Word 自帶的“比較&#xff08;Compare&#xff09;”功能&#xff0c;步驟如下&#xff1a; ? 方法一&#xff1a;使用 Microsoft Word 的“比較”功能 打開 Microsoft Word。 點擊頂部菜單欄中的 “…