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。

相关推荐
培风图南以星河揽胜1 天前
Java版LeetCode热题100之零钱兑换:动态规划经典问题深度解析
java·leetcode·动态规划
想进个大厂2 天前
代码随想录day32 动态规划01
算法·动态规划
Ronaldinho Gaúch2 天前
leetcode279完全平方数
c++·算法·动态规划
代码无bug抓狂人2 天前
动态规划习题篇(不同路径和整数拆分)
算法·动态规划
代码无bug抓狂人2 天前
动态规划(附带入门例题)
c语言·算法·动态规划
Snow_day.2 天前
有关线段树应用(1)
数据结构·算法·贪心算法·动态规划·图论
yzp-3 天前
动态规划-------- dp数组套路学习
学习·算法·动态规划
好易学·数据结构3 天前
可视化图解算法78:整数拆分
数据结构·算法·leetcode·面试·动态规划·笔试·机试
Wuliwuliii5 天前
高维子集和&子集染色问题
动态规划·dp·子集·子集和·多维子集和
Tisfy5 天前
LeetCode 3651.带传送的最小路径成本:动态规划
算法·leetcode·动态规划·题解·排序