Leetcode 3389. Minimum Operations to Make Character Frequencies Equal

  • [Leetcode 3389. Minimum Operations to Make Character Frequencies Equal](#Leetcode 3389. Minimum Operations to Make Character Frequencies Equal)
    • [1. 解题思路](#1. 解题思路)
    • [2. 代码实现](#2. 代码实现)

1. 解题思路

这一题从答题从test的结果来说来说做出的人很少,主要确实有些繁琐,因为还是那种分类讨论的问题,然后思路上也比较暴力。

这道题我自己也没有完全自力搞定,因为一开始觉得不会这么暴力,然后就没怎么找到思路,结果看了一下大佬们的回答之后发现核心思路其实差不多,只不过我觉得铁定超时就没有往下去尝试,然后大佬做了,然后就过了......

这道题思路上如前所述,非常的暴力,就是遍历所有可能的最终值情况下各自需要多少操作,然后取最小值。

因此,这里的核心问题就变成了,给定一个最终值 k k k,如何计算将原始字符串变换为最终所有的字符都为 k k k个所需的最小操作次数。

而这个又是可以通过动态规划来进行实现,只不过每一个值都需要考虑以下几种情况:

  1. 当前值变为 0 0 0,下一个值变为 k k k
  2. 当前值变为 0 0 0,下一个值也变为 0 0 0
  3. 当前值变为 k k k,下一个值变为 0 0 0
  4. 当前值变为 k k k,下一个值也变为 k k k

另外,如果当前值如果需要减少现有值的情况下,需要考察下一个值是否需要增加值,如果需要的话需要使用操作3来进行操作复用。

可以看到,这个逻辑还是蛮复杂的,需要一些分类讨论,但整体理清楚了思路就整体还是挺直接的了。

2. 代码实现

我们给出最终的python代码实现如下:

python 复制代码
class Solution:
    def makeStringGood(self, s: str) -> int:
        cnt = Counter(s)

        @lru_cache(None)
        def count_op(tgt):
            nums = [cnt[ch] for ch in string.ascii_lowercase]

            @lru_cache(None)
            def dfs(idx, nxt):
                if idx == 25:
                    current = nums[idx] + nxt
                    return min(current, abs(tgt-current))
                ans = math.inf
                
                current = nums[idx] + nxt
                nxt = nums[idx+1]
                if current == 0 or current == tgt:
                    return dfs(idx+1, 0)
                if nxt == 0 or nxt >= tgt:
                    ans = min(ans, min(current, abs(current-tgt)) + dfs(idx+1, 0))
                elif current > tgt:
                    ans = min(
                        ans, 
                        current-tgt + dfs(idx+1, 0),
                        current-tgt + dfs(idx+1, min(tgt-nxt, current-tgt))
                    )
                else:
                    ans = min(
                        ans, 
                        tgt-current + dfs(idx+1, 0),
                        current + dfs(idx+1, 0),
                        current + dfs(idx+1, min(tgt-nxt, current))
                    )
                return ans
            
            ans = dfs(0, 0)
            return ans              
            
        ans = min(count_op(i) for i in range(1, max(cnt.values())+1))
        return ans

提交代码评测得到:耗时1115ms,占用内存19.8MB。

相关推荐
xsyaaaan9 小时前
代码随想录Day30动态规划:背包问题二维_背包问题一维_416分割等和子集
算法·动态规划
我是咸鱼不闲呀12 小时前
力扣Hot100系列19(Java)——[动态规划]总结(上)(爬楼梯,杨辉三角,打家劫舍,完全平方数,零钱兑换)
java·leetcode·动态规划
xhbaitxl15 小时前
算法学习day39-动态规划
学习·算法·动态规划
xhbaitxl18 小时前
算法学习day38-动态规划
学习·算法·动态规划
2501_924878731 天前
数据智能驱动进化:AdAgent 多触点归因与自我学习机制详解
人工智能·逻辑回归·动态规划
YYuCChi2 天前
代码随想录算法训练营第三十七天 | 52.携带研究材料(卡码网)、518.零钱兑换||、377.组合总和IV、57.爬楼梯(卡码网)
算法·动态规划
罗湖老棍子2 天前
括号配对(信息学奥赛一本通- P1572)
算法·动态规划·区间dp·字符串匹配·区间动态规划
一只小小的芙厨2 天前
寒假集训笔记·树上背包
c++·笔记·算法·动态规划
金融RPA机器人丨实在智能2 天前
2026动态规划新风向:实在智能Agent如何以自适应逻辑重构企业效率?
算法·ai·重构·动态规划
问好眼2 天前
【信息学奥赛一本通】1275:【例9.19】乘积最大
c++·算法·动态规划·信息学奥赛