100255. 成为 K 特殊字符串需要删除的最少字符数
题目![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/7f95897f5a03e1eaf53b26f088f6e1f1.png)
代码
class Solution {
// 方法接受一个字符串word和一个整数k,返回使word成为k特殊字符串需要删除的字符的最小数量
public int minimumDeletions(String word, int k) {
// cnts数组用于记录字符串中每个字符的出现次数
int[] cnts = new int[26];
for (char c : word.toCharArray()) {
cnts[c - 'a']++;
}
// list用于存储非零出现次数
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 26; i++) {
if (cnts[i] != 0) {
list.add(cnts[i]);
}
}
// 对字符频率进行排序,以便按顺序处理
Collections.sort(list);
// 动态规划数组,用于存储到当前字符为止需要删除的最小字符数
int[] dp = new int[list.size()];
// l是当前考虑的字符频率的最小值
int l = list.get(0);
// 寻找第一个需要进行调整的字符频率索引
int index = -1;
for (int i = 0; i < list.size(); i++) {
if (list.get(i) > l + k) {
index = i;
break;
}
}
// 如果所有字符频率已经符合k特殊字符串的条件,则无需删除任何字符
if (index == -1) return 0;
// 初始化dp[0],计算出从第一个需要调整的频率开始,达到k特殊字符串所需的删除次数
for (int i = index; i < list.size(); i++) {
dp[0] += (list.get(i) - (l + k));
}
// ans记录最小的删除次数
int ans = dp[0];
// 通过动态规划,更新每个字符频率调整后的最小删除次数
for (int i = 1; i < list.size(); i++) {
int cnt1 = list.get(i - 1); // 当前频率与前一个频率的差值
int j = index;
int cnt2 = 0;
// 更新dp数组,并计算每一步的最小删除数
for (j = index; j < list.size(); j++) {
if (list.get(j) > list.get(i) + k) break;
cnt2 -= (list.get(j) - (list.get(i - 1) + k));
}
cnt2 -= ((list.size() - j) * (list.get(i) - list.get(i - 1)));
index = j;
dp[i] = dp[i - 1] + cnt1 + cnt2; // 更新dp[i]为到当前步骤的最小删除数
ans = Math.min(ans, dp[i]); // 更新最小删除数
}
// 返回最小删除数,即将word转换为k特殊字符串所需的最小删除操作数
return ans;
}
}
字符频率统计
首先,解决方案通过遍历字符串word
,计算并存储每个字符的出现次数。这是通过创建一个长度为26的整型数组cnts
完成的,数组的每个元素对应一个英文字母的出现频率。这个统计过程是为了后续分析字符频率分布的基础。
频率分布分析
将所有非零频率的字符统计出来并放入列表list
中,这一步的目的是将关注点限定在实际出现在字符串中的字符上,避免了处理未出现字符的不必要计算。然后,对这个列表按照频率进行排序,使得接下来的操作可以按照频率的升序进行,为调整频率和计算删除数提供方便。
确定调整需求
通过比较排序后的频率列表中的元素,确定哪些字符的频率需要调整以满足k
特殊字符串的定义。这涉及到查找列表中第一个频率加k
还小于其后某元素频率的点。如果所有字符的频率已经满足条件(即差值不超过k
),则不需要进行任何删除。
动态规划求解
采用动态规划方法计算需要删除的最小字符数量。动态规划的核心在于用一个数组dp
来记录到达每一步所需的最小删除操作数。dp
数组的每个元素dp[i]
表示从频率列表的第i
个元素开始进行调整时,到达当前状态所需的最小删除数。
这里的关键逻辑是,对于每个频率点,尝试通过增加或减少字符来达到目标频率分布,同时记录所需的最小删除数。这个过程涉及比较复杂的计算,包括但不限于计算从某一频率值开始调整到满足k
特殊字符串条件所需的删除数。
最小删除数确定
最后,通过比较所有可能的调整起点,确定了实现k
特殊字符串条件下的最小删除操作数。这意味着算法不仅考虑了从每个字符频率点开始的调整方案,而且还通过动态规划找到了最优解。
总结
这个解决方案通过细致地分析字符频率分布,并运用动态规划技术来优化调整过程,有效地找到了将任意字符串转换成k
特殊字符串所需的最小删除操作数。这种方法的优势在于它能够在保证结果正确性的同时,最小化所需的操作数量,从而高效解决问题。