LeetCode3月17周赛(100255. 成为 K 特殊字符串需要删除的最少字符数)

文章讲述了如何使用代码实现一个Solution类,通过字符频率统计、动态规划方法来确定将给定字符串转换为满足特定条件(K特殊字符串)所需的最少删除字符数。
摘要由CSDN通过智能技术生成

题目在这里插入图片描述

代码

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特殊字符串所需的最小删除操作数。这种方法的优势在于它能够在保证结果正确性的同时,最小化所需的操作数量,从而高效解决问题。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值