压缩字符串 II
难度:
标签:
题目描述
代码结果
运行时间: 308 ms, 内存: 17.5 MB
/*
* 思路:
* 使用Java Stream的方式进行优化,尽量使用Lambda表达式和流操作来简化代码结构。
* 这仍然是基于动态规划的解决方案。
*/
import java.util.stream.IntStream;
import java.util.Arrays;
public class Solution {
public int getLengthOfOptimalCompression(String s, int k) {
int n = s.length();
int[][] dp = new int[n + 1][k + 1];
Arrays.stream(dp).forEach(a -> Arrays.fill(a, Integer.MAX_VALUE));
dp[0][0] = 0;
IntStream.rangeClosed(1, n).forEach(i -> IntStream.rangeClosed(0, k).forEach(j -> {
if (j > 0) dp[i][j] = dp[i - 1][j - 1];
int[] count = {0};
int[] deletions = {0};
IntStream.rangeClosed(i, n).forEach(l -> {
if (s.charAt(l - 1) == s.charAt(i - 1)) count[0]++;
else deletions[0]++;
if (j - deletions[0] >= 0) dp[l][j] = Math.min(dp[l][j], dp[i - 1][j - deletions[0]] + 1 + (count[0] >= 100 ? 3 : count[0] >= 10 ? 2 : count[0] >= 2 ? 1 : 0));
});
}));
return dp[n][k];
}
}
解释
方法:
此题解采用深度优先搜索(DFS)与记忆化的方法。首先,定义一个辅助函数dfs(n, k),表示考虑前n个字符,允许删除k个字符时的最小压缩长度。使用记忆化存储,避免重复计算相同状态。在dfs函数中,首先检查递归结束条件,即当剩余字符数量小于等于可删除字符数量时,返回0。然后,检查当前状态是否已经计算过,如果是,则直接返回结果。接着,处理特殊情况,即当k为0时,计算不删除任何字符的压缩长度。最后,遍历剩余字符,对于每个字符,计算删除和不删除该字符的情况下的最小压缩长度,并更新结果。整体思路是通过递归分治的方式,枚举所有可能的删除操作,找到最优解。
时间复杂度:
O(k * n^2)
空间复杂度:
O(n * k)
代码细节讲解
🦆
在递归函数dfs中,'当剩余字符数量小于等于可删除字符数量时,返回0'这一逻辑的依据是什么?是否意味着所有剩余字符都将被删除?
▷🦆
递归函数中,当k为0时直接计算不删除任何字符的压缩长度,这种处理方式是否考虑了所有字符都是相同的情况,其计算方式是否正确?
▷🦆
在处理k不为0的情况时,你是如何决定是否删除字符或保留字符来尝试获取最小压缩长度的?具体的策略和逻辑是什么?
▷