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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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。 点击顶部菜单栏中的 “…