首先想到的是用回溯的方法暴力求解,遍历所有可能的情况。感觉大概率会超出时间限制。
维护全局变量 res 存储当前遍历到的硬币数量的最大值。
1)递归函数参数:当前可戳的气球 balloon,已有的硬币数量 icons(初始化为0)
2)递归函数内容:
(1)如果 balloon 为空,对比当前 icons 与 res,将res更新为最大值
(2)如果 balloon 不为空,遍历各个气球,戳破遍历到的气球,更新icons,调用递归函数。
实现代码如下,感觉必然会超出时间限制
func maxCoins(nums []int) int {
var res int=0
var helper func(balloon []int, icons int)
helper = func(balloon []int, icons int){
// fmt.Println(balloon, icons)
if len(balloon)==0{
res = getMax(res, icons)
}else{
var left, right int=1, 1
for k, v := range balloon{
if k==0 { left=1 } else { left=balloon[k-1] }
if k==len(balloon)-1 { right=1 } else { right=balloon[k+1] }
newBalloon := append([]int{}, balloon[:k]...)
newBalloon = append(newBalloon, balloon[k+1:]...)
helper(newBalloon, icons+left*v*right)
}
}
}
helper(nums, 0)
return res
}
func getMax(a, b int) int {
if a>=b {
return a
}else { return b }
}
果然超出了时间限制,它要不超可能也不至于在困难类了。
1)剪枝:考虑什么情况下能够确定当前情况必然不是最优解,想了一下并没有想到。
2)空间换时间:首先想到的就是将之前遍历的情况存储起来,递归之前查看之前已经遍历过的,如果已经存储,证明该种情况已经考虑过,不再进行重复运算,但是也没有想到什么好的解法
3)灵机一动:脑子里动了动,感觉没动出个啥来,看看别的大神怎么解吧,学习一下([LeetCode] 312. Burst Balloons 打气球游戏 - Grandyang - 博客园 (cnblogs.com))。
果然应该想一下动态的,大意了大意了。动态规划考虑两个方面,子状态(dp数组里存什么)以及状态转移方程(如何根据小的dp数组得到大的dp数组)。
1)子状态:二维数组 dp ,其中dp[i][j],存储戳爆 [i, j] 区间内的全部气球时所能获得的最多硬币
2)状态转移方程:dp[i][j]的值应该为以下两者中的较大值,假设戳 [i, j] 区间中的第k个气球
3)还有一个需要注意的点,通常情况下想到的子状态遍历方法是按照数组的下标进行遍历,但是这里不太一样,是按照区间的长短进行遍历,也就是说首先遍历长度为1所有可能区间,在根据长度为1的区间,计算长度为2区间的所有可能情况,以此类推。
实现代码如下:
func maxCoins(nums []int) int {
var l int = len(nums)
var dp [][]int = make([][]int, l+2)
for k, _:=range dp{ dp[k]=make([]int, l+2) }
// 首尾添加1,方便计算
balloons := append([]int{1}, nums...)
balloons = append(balloons, 1)
for n:=1; n<=l; n++{ // 从长度为1的区间开始遍历
for i:=1; i<=l-n+1; i++{ // 区间的开始位置
j:=i+n-1 // 区间的结束位置
for k:=i; k<=j; k++{
dp[i][j]=getMax(dp[i][j], dp[i][k-1]+dp[k+1][j]+balloons[i-1]*balloons[k]*balloons[j+1])
}
}
}
return dp[1][l]
}
func getMax(a, b int) int {
if a>=b {
return a
}else { return b }
}
注意:一开始划分区间的时候使用了 dp[i][k]+dp[k+1][j]+nums[i-1]*nums[k]*nums[j+1],然后发现自己将切片的下标思想带入了,dp[i][k]区间会将第k个气球戳破,但实际上不应该戳破,应该为dp[i][k-1]