【LeetCode 每日一题】1653. 使字符串平衡的最少删除次数——(解法三)DP 空间优化

Problem: 1653. 使字符串平衡的最少删除次数

文章目录

  • [1. 整体思路](#1. 整体思路)
  • [2. 完整代码](#2. 完整代码)
  • [3. 时空复杂度](#3. 时空复杂度)
      • [时间复杂度: O ( N ) O(N) O(N)](#时间复杂度: O ( N ) O(N) O(N))
      • [空间复杂度: O ( 1 ) O(1) O(1)](#空间复杂度: O ( 1 ) O(1) O(1))

1. 整体思路

核心问题

删除最少字符使得字符串中所有的 'a' 都在 'b' 之前。

算法逻辑

使用动态规划,并利用滚动变量进行状态压缩。

  • 状态 f :代表遍历到当前位置时,使当前前缀字符串平衡所需的最少删除次数 (相当于之前的 dp[i])。
  • 变量 cntB :记录当前遍历到的 'b' 的总数量
  • 状态转移
    • 遍历字符串 s
    • 如果当前字符是 'b'
      • 这个 'b' 可以直接追加在任何已经平衡的字符串后面,不会破坏平衡性。
      • 因此,最小删除次数 f 保持不变
      • 更新 cntB(加 1)。
    • 如果当前字符是 'a'
      • 此时有两个选择来维持平衡:
        1. 删除当前的 'a' :代价是之前的最小删除次数 f 加上这次删除的代价 1。即 f + 1
        2. 保留当前的 'a' :这意味着这个 'a' 必须放在所有的 'b' 之前。为了做到这一点,我们必须删除之前出现的所有 'b' 。代价是 cntB
      • 更新 f 为两者的最小值:f = Math.min(f + 1, cntB)

2. 完整代码

java 复制代码
class Solution {
    public int minimumDeletions(String s) {
        // f 记录当前位置之前的最小删除次数
        // 初始化为 0,因为空前缀是平衡的
        int f = 0;
        
        // cntB 记录当前遍历过的 'b' 的数量
        int cntB = 0;
        
        // 遍历字符串中的每个字符
        // toCharArray() 会创建一个新的字符数组,如果为了极致空间可以换成 charAt()
        for (char c : s.toCharArray()) {
            if (c == 'b') {
                // 如果当前是 'b',它不会破坏平衡性 (因为我们在向右构建,b 总是在右边)
                // 只需要记录 b 的数量增加
                cntB++;
            } else {
                // 如果当前是 'a',它可能会破坏平衡性 (因为它出现在了之前的 b 后面)
                // 我们有两种修复方案:
                // 1. 删除这个 'a' (代价 f + 1)
                // 2. 保留这个 'a',但删除前面所有的 'b' (代价 cntB)
                // 取较小者作为新的最小删除次数
                f = Math.min(f + 1, cntB);
            }
        }
        
        // 返回最终的最小删除次数
        return f;
    }
}

3. 时空复杂度

假设字符串 s 的长度为 N N N。

时间复杂度: O ( N ) O(N) O(N)

  • 计算依据
    • 代码包含一次线性遍历,访问每个字符一次。
    • 循环内部操作为 O ( 1 ) O(1) O(1)。
  • 结论 : O ( N ) O(N) O(N)。

空间复杂度: O ( 1 ) O(1) O(1)

  • 计算依据
    • 只使用了两个整型变量 fcntB
    • 虽然使用了 s.toCharArray() 产生了 O ( N ) O(N) O(N) 的临时空间,但如果在面试中可以直接用 charAt 遍历,算法逻辑本身是 O ( 1 ) O(1) O(1) 的。
  • 结论 : O ( 1 ) O(1) O(1)。
相关推荐
猿人谷3 小时前
不只是 CPU 阈值:STAR 如何用 GAT + Transformer 做容器级自动扩缩容?
人工智能·算法
复杂网络4 小时前
Stable Diffusion 视觉大模型微调技术深度调研
算法
复杂网络5 小时前
基于 Stable Diffusion 架构的视觉大模型代表性工作与原理深度解析
算法
MrZhao4005 小时前
Agent Loop 如何用 Hook 扩展:权限、日志与工具拦截
算法
MrZhao4005 小时前
Agent 为什么需要 Skills:别把所有知识都塞进 system prompt
算法
JieE2122 天前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
JieE2123 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack203 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树3 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2124 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法