LeetCode312 戳气球
题目
有 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]
输出:10
提示:
n == nums.length
1 <= n <= 500
0 <= nums[i] <= 100
方法
一般取最值需要遍历所有情况比较后才能得出最值,遍历一般分为自上而下的遍历(dfs)和自下而上的遍历(动态规划),我们可以将戳气球的过程反向思考,变为一排灯先亮哪个,即最后一个戳破的气球为第一个亮起的灯,我们把边界条件添加进数组中,因此此题目可看作求(0,n+1)范围内的亮灯问题,当选取下标为k的灯为(i,j)范围第一个亮的灯的话,他的硬币数为val(i)val(k)val(j),下一步考虑(i,k)区间和(k,j)区间的,因此我们可得出状态方程:
dp[i,j] = max(val(i)val(k)val(j)) + dp[i,k]+dp[k,j]
深度优先遍历
class Solution {
public int maxCoins(int[] nums) {
int length = nums.length;
int[] val = new int[length+2];
val[0] = val[length+1] = 1;
for(int i=0;i<length;i++){
val[i+1] = nums[i];
}
return dfs(val,0,length+1);
}
private int dfs(int[] val,int i,int j){
if(i>=j-1){
return 0;
}
int res = 0;
for(int k = i+1;k<j;k++){
int sum = val[i]*val[k]*val[j]+ dfs(val,i,k)+dfs(val,k,j);
res = Math.max(res,sum);
}
return res;
}
}
深度优先遍历+记忆化优化
深度优先遍历计算过程中一些区间重复计算,因此可以用数组保存区间最大值
- 时间复杂度:O(n^3),n为数组长度
- 空间复杂度:O(n^2)
(区间)动态规划法
第一步:把边界条件加入数组,重新构造一个带边界的数组val
第二步:按动态规划状态方程计算,由于dp[i,j]需要dp[i,k],dp[k,j],因此i需要从大到小,j则从i+2到最后,所以i从n-1到0
- 时间复杂度:O(n^3),n为数组长度
- 空间复杂度:O(n^2)
class Solution {
public int maxCoins(int[] nums) {
int length = nums.length;
int[] val = new int[length+2];
int[][] dp = new int[length+2][length+2];
val[0] = val[length+1] = 1;
for(int i=0;i<length;i++){
val[i+1] = nums[i];
}
for(int i=length-1;i>=0;i--){
for(int j=i+2;j<=length+1;j++){
for(int k=i+1;k<j;k++){
int sum = val[i]*val[k]*val[j]+dp[i][k]+dp[k][j];
dp[i][j] = Math.max(dp[i][j],sum);
}
}
}
return dp[0][length+1];
}
}
分类:
LeetCode Hot100
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理