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 天前
【算法】——动态规划算法及实践应用
数据结构·c++·算法·动态规划
橘颂TA1 天前
【剑斩OFFER】算法的暴力美学——将 x 减到零的最小操作数
c++·算法·leetcode·动态规划
十八岁讨厌编程2 天前
【算法训练营Day30】动态规划part6
算法·动态规划
_dindong2 天前
动规:01背包
数据结构·笔记·学习·算法·leetcode·动态规划·力扣
Espresso Macchiato3 天前
Leetcode 3698. Split Array With Minimum Difference
leetcode medium·分类讨论·leetcode周赛469·leetcode 3698
Espresso Macchiato3 天前
Leetcode 3700. Number of ZigZag Arrays II
动态规划·leetcode hard·矩阵乘法·leetcode 3700·leetcode周赛469
未知陨落3 天前
LeetCode:84.完全平方数
算法·leetcode·动态规划
dragoooon344 天前
[优选算法专题三.二分查找——NO.24搜索旋转排序数组中的最⼩值]
数据结构·leetcode·动态规划
Espresso Macchiato4 天前
Leetcode 3695. Maximize Alternating Sum Using Swaps
并查集·leetcode hard·dsu·uf·leetcode 3695·leetcode双周赛166
十八岁讨厌编程6 天前
【算法训练营Day27】动态规划part3
算法·动态规划