01背包面试题系列(二)
01背包面试题系列(二)
题目描述——最后一块石头的重量 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
前言
本文所谈到的题目是01背包问题的一个变种,如果你还不是很了解01背包的话,可以先看这篇文章,该文章主要从0开始介绍了01背包问题,从二维数组到滚动数组再到一维数组,优化过程层层递进,带你从原理到实战完全掌握01背包问题。
问题分析
在读完题目之后,我们的第一感觉就是,如果我们能过恰好将所有的物品分成重量相同的两堆就好了,这样最终剩下的石头的重量就等于0!比如说我们分成的两堆石头的重量分别为[1, 2, 3, 4, 5]
, [10, 2, 3]
,那么我们就可以使用[2, 3, 5]
和[10]
进行碰撞,这样最后剩下的重量为0, 现在还剩下[1, 4]
和[2, 3]
,那么我们可以使用[4]
和[3]
进行碰撞,那么剩下的为[1, 1]
和[2]
,那么碰完之后剩下石头的重量就等于0了。
在经过上面的例子之后你看你已经理解为什么我们要将所有的石头尽可能的分成两堆重量一样的了,即使重量不一样我们也需要尽可能的将他们之间的差距变小,最后剩下的物品的重量就等于所有物品的重量和减去重量较小的一堆的2倍。
假设所有的石头的重量和为
如果能够恰好装满篮子那么我们恰好能够将所有的石头分成两份重量相等的石头,最终剩下的重量为
问题转化
如果你之前已经了解过01背包问题相信在经过上面的分析之后你会发现,这个问题可以转化成一个背包问题,因为我们在经过上面的问题转换之后,我们的任务变成了,对于每个石头我们可以选择一次,它的重量和价值相等,当我们的背包能够承受的重量等于所有石头重量和的一半时,我们能够获取的最大的价值是多少?在上文当中我们说的是,如果我们有一个篮子,他可以承受的重量为
单行数组优化代码
class Solution { public int lastStoneWeightII(int[] stones) { int sum = 0; for (int stone : stones) { sum += stone; } int v = sum / 2 + 1; int[] f = new int[v]; for (int i = 0; i < stones.length; i++) { for (int j = v - 1; j >= stones[i]; j--) { f[j] = Math.max(f[j], f[j - stones[i]] + stones[i]); } } return sum - 2 * f[v - 1]; } }
总结
本文主要给大家介绍最后一块石头的重量 II这个题目,这个题目主要就是一个01背包的变种,主要要的问题就是如何将这个问题转化成01背包问题,这是本文所提到的问题的解决核心,其实在很多算法题当中,最终要的就是需要学会将问题进行转化,将一个不熟悉的问题转化成一个我们熟悉的算法。使用动态规划求解的方法还是比较抽象,可能需要大家花时间好好琢磨一下,希望大家有所收获,我是LeHung,我们下期再见!!!(记得点赞收藏哦!)
更多精彩内容合集可访问项目:https://github.com/Chang-LeHung/CSCore
关注公众号:一无是处的研究僧,了解更多计算机(Java、Python、计算机系统基础、算法与数据结构)知识。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构