给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色。
你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止。每一轮你可以移除具有相同颜色的连续 k 个盒子(k >= 1),这样一轮之后你将得到 k*k 个积分。
当你将所有盒子都去掉之后,求你能获得的最大积分和。
示例 1:
输入:
[1, 3, 2, 2, 2, 3, 4, 3, 1]
输出:
23
解释:
[1, 3, 2, 2, 2, 3, 4, 3, 1]
—-> [1, 3, 3, 4, 3, 1] (3*3=9 分)
—-> [1, 3, 3, 3, 1] (1*1=1 分)
—-> [1, 1] (3*3=9 分)
—-> [] (2*2=4 分)
提示:盒子的总数 n 不会超过 100。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-boxes
方法 1:暴力方法【超时】
算法
暴力方法是显然的,我们试图移除每一个可能的元素,并计算得分以及剩下的序列继续递归。
最后,dpdp 的更新式为:\text{dp[l][r][k]} = max(\text{dp[l][r][k]}, \text{dp[l][i][k+1]} + \text{dp[i+1][r-1][0]})dp[l][r][k]=max(dp[l][r][k],dp[l][i][k+1]+dp[i+1][r-1][0])。
最后,dp[0][n-1][0] 就是最后的结果。实现如下,使用 calculatePoints 函数用递归更好的计算结果。
Java
public class Solution {
public int removeBoxes(int[] boxes) {
return remove(boxes);
}
public int remove(int[] boxes)
{
if(boxes.length==0)
return 0;
int res=0;
for(int i=0,j=i+1;i<boxes.length;i++)
{
while(j<boxes.length && boxes[i]==boxes[j])
j++;
int[] newboxes=new int[boxes.length-(j-i)];
for(int k=0,p=0;k<boxes.length;k++)
{
if(k==i)
k=j;
if(k<boxes.length)
newboxes[p++]=boxes[k];
}
res=Math.max(res,remove(newboxes)+(j-i)*(j-i));
}
return res;
}
}
复杂度分析
时间复杂度:O(n!),f(n) 是找到 n个盒子有 nn 种不同颜色的方案,显然 f(n-1)f(n)=n×f(n−1),所以结果 n! 是时间复杂度。
空间复杂度:O(n^2)
方法 2:记忆化搜索
算法
记忆化搜索
令dp[i][j]表示从j开始,长度为i的字符串。
dp[i][j] = Math.max(dp[i-1][j] + 1, 最后一个字符与前面任意多个相同字符联合起来得分的最大值);
所以对于dp,需要使用深度搜索找到 最后一个字符,与前面任意多个字符联合起来的最大得分。
Java
class Solution {
public int removeBoxes(int[] boxes) {
int[][][] dp = new int[100][100][100];
return calculatePoints(boxes, dp, 0, boxes.length - 1, 0);
}
public int calculatePoints(int[] boxes, int[][][] dp, int l, int r, int k) {
if (l > r) return 0;
if (dp[l][r][k] != 0) return dp[l][r][k];
while (r > l && boxes[r] == boxes[r - 1]) {
r--;
k++;
}
dp[l][r][k] = calculatePoints(boxes, dp, l, r - 1, 0) + (k + 1) * (k + 1);
for (int i = l; i < r; i++) {
if (boxes[i] == boxes[r]) {
dp[l][r][k] = Math.max(dp[l][r][k], calculatePoints(boxes, dp, l, i, k + 1) + calculatePoints(boxes, dp, i + 1, r - 1, 0));
}
}
return dp[l][r][k];
}
}
复杂度分析
时间复杂度:O(n^4)要填满所有 dp 数组。
空间复杂度:O(n^3),dp 的数组大小。