力扣题312戳气球
发布日期:2022-03-04 11:48:16
浏览次数:6
分类:技术文章
本文共 4131 字,大约阅读时间需要 13 分钟。
有 n 个气球,编号为0 到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中。
现在要求你戳破所有的气球。戳破第 i 个气球,你可以获得 nums[i - 1] * nums[i] * nums[i + 1] 枚硬币。 这里的 i - 1 和 i + 1 代表和 i 相邻的两个气球的序号。如果 i - 1或 i + 1 超出了数组的边界,那么就当它是一个数字为 1 的气球。
求所能获得硬币的最大数量。
示例 1:
输入:nums = [3,1,5,8] 输出:167 解释: nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> [] coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167 示例 2:输入:nums = [1,5]
输出:101.自己的解法:想用回溯法,把每种和都计算出来,然后取最大值。
这种方法可以通过测试用例,但是提交后显示超出时间限制。因为使用这种回溯法,会造成
大量的重复计算。
class Solution { int maxCount = 0;//记录最大值 public int maxCoins(int[] nums) { boolean[] isVisited = new boolean[nums.length];//存储每个气球的状态,是否被戳破 maxCoins(nums,isVisited,0,0); return maxCount; } public void maxCoins(int[] nums,boolean[] isVisited,int curCount,int length) { if (length == nums.length) {//所有气球都被戳皮后,比较是否需要更新最大值 maxCount = Math.max(maxCount,curCount); return; } for (int i = 0;i < nums.length;i++) {//遍历每种情况 int curNum = curNum(nums,isVisited,i);//计算当前气球被戳破的话可以得到多少硬币 if (!isVisited[i]) {//如果当前气球没有被戳破过 curCount += curNum;//加上硬币数 isVisited[i] = true;//更新气球状态 maxCoins(nums,isVisited,curCount,length + 1); } else{//如果当前气球被戳破了,直接跳过 continue; } //回溯 isVisited[i] = false; curCount -= curNum; } } //该函数用来计算每个气球被戳破的话能够得到多少硬币 public int curNum(int[] nums,boolean[] isVisited,int index) { int left = index - 1; int right = index + 1; while (left >= 0 && isVisited[left]) {//找到左侧第距离最近的未被戳破的气球 left--; if (left < 0) { break; } } while (right <= nums.length - 1 && isVisited[right]) {//找到右侧距离最近的未被戳破的气球 right++; if (right > nums.length - 1) { break; } } if (left < 0 && right > nums.length - 1) {//左右不存在未戳破的气球的情况 return 1 * nums[index] * 1; } else if (left < 0) {//只有左侧气球被戳破的情况 return 1 * nums[index] * nums[right]; } else if (right > nums.length - 1) {//只有右侧气球被戳破的情况 return nums[left] * nums[index] * 1; } else {//两侧气球均未被戳破的情况 return nums[left] * nums[index] * nums[right]; } }}
2.题解:为了方便处理,我们对nums数组稍作处理,将其两边各加上题目中假设存在的 nums[−1] 和nums[n] ,并保存在val 数组中,即]val[i]=nums[i−1] 。之所以这样处理是为了处理nums[−1] ,防止下标越界。
记忆化搜索:
class Solution { public int[][] rec;//存储每个区间的最大值 public int[] val;//存储每个气球值 public int maxCoins(int[] nums) { int n = nums.length; val = new int[n + 2]; val[0] = val[n + 1] = 1;//在开头和末尾各自加上一个1,方便计算 for (int i = 1;i <= n;i++) { val[i] = nums[i - 1]; } rec = new int[n+2][n+2]; for (int i = 0;i <= n + 1;i++) { Arrays.fill(rec[i],-1); } return solve(0,n+1); } public int solve(int left,int right) { if (left >= right - 1) {//表示所有气球都被戳完了 return 0; } if (rec[left][right] != -1) { // 这个区间的最大值之前已经计算过了,直接返回,避免重复计算 return rec[left][right]; } for (int i = left + 1;i < right;i++) { int sum = val[left] * val[i] * val[right];//当前气球被戳破的到的硬币数 sum += solve(left,i) + solve(i,right);//递归计算左侧最大和与右侧最大和 rec[left][right] = Math.max(rec[left][right],sum);//更新当前区间的最大值 } return rec[left][right]; }}
动态规划:
class Solution { public int maxCoins(int[] nums) { int n = nums.length; int[] val = new int[n + 2]; val[0] = val[n + 1] = 1;//在开头和末尾各自加上一个1,方便计算 for (int i = 1;i <= n;i++) { val[i] = nums[i - 1]; } int[][] rec = new int[n+2][n+2]; //开区间 //i从末端开始,为了从小区间得到大区间 for (int i = n - 1;i >= 0;i--) {//开区间左侧起点 for (int j = i + 2;j <= n + 1;j++) {//右侧中点 for (int k = i + 1;k < j;k++) {//这个开区间的中间值 int sum = val[i] * val[k] * val[j]; sum += rec[i][k] + rec[k][j]; rec[i][j] = Math.max(rec[i][j],sum); } } } return rec[0][n + 1]; }}
题源:
转载地址:https://blog.csdn.net/xxyneymar/article/details/122029209 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月12日 12时45分12秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
css3 属性 text-overflow 实现截取多余文字内容 以省略号来代替多余内容
2019-04-27
vue 事件总线EventBus的概念、使用以及注意点
2019-04-27
JavaScript 用七种方式教你判断一个变量是否为数组类型
2019-04-27
黄家懿:河北高校邀请赛 -- 二手车交易价格预测决赛答辩
2019-04-27
如何利用pyecharts绘制酷炫的桑基图?
2019-04-27
王朝阳:河北高校邀请赛 -- 二手车交易价格预测决赛答辩
2019-04-27
Scratch等级考试(二级)模拟题
2019-04-27
如何在Jupyter Lab中显示pyecharts的图形?
2019-04-27
什么是Python之禅?
2019-04-27
【青少年编程】【Scratch】01 运动模块
2019-04-27
json的序列化与反序列化
2019-04-27
【第16周复盘】学习的飞轮
2019-04-27
如何利用pyecharts绘制炫酷的关系网络图?
2019-04-27
NCEPU:线下组队学习周报(007)
2019-04-27
【青少年编程】【二级】寻找宝石
2019-04-27
【组队学习】【26期】Linux教程
2019-04-27
解决 nginx: [error] open() “/usr/local/nginx/logs/nginx.pid“ failed (2: No such file or directory) 问题
2019-04-27
LeetCode-122. 买卖股票的最佳时机 II(Goland实现)
2019-04-27
LeetCode-136. 只出现一次的数字(Goland实现)
2019-04-27
go-递归实现二叉树的三种排序方式(前序、中序、后序)【详细】
2019-04-27