【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)

  • 计算依据 :
    • 只使用了两个整型变量 f 和 cntB。
    • 虽然使用了 s.toCharArray() 产生了 O ( N ) O(N) O(N) 的临时空间,但如果在面试中可以直接用 charAt 遍历,算法逻辑本身是 O ( 1 ) O(1) O(1) 的。
  • 结论 : O ( 1 ) O(1) O(1)。
相关推荐
ra90fy3 分钟前
B3873 [GESP202309 六级] 小杨买饮料
c++·算法
Omics Pro12 分钟前
北理工李荣华:AI虚拟细胞证据多模态推理基准
数据库·人工智能·算法·机器学习·自然语言处理
Cccp.12314 分钟前
【leetcode】(九)哈希函数与哈希表
数据结构·leetcode·哈希算法
xieliyu.17 分钟前
LeetCode 1419 数青蛙:状态模拟求最少青蛙数量|Java 题解
java·算法·leetcode
acd1200919 分钟前
线上偶发 499 错误,并非后端服务异常
算法
Nil20824 分钟前
leetcode 45跳跃游戏Ⅱ
算法·leetcode·游戏
小蒋观天下41 分钟前
端侧大模型在安防摄像头部署实操(下篇)|模型量化、推理加速、视频接入与量产调优
大数据·人工智能·算法·安全·机器学习·计算机视觉·ai大模型
sinat_286945191 小时前
大模型推理:部署方式与性能优化思路
人工智能·算法·缓存·chatgpt·性能优化
longlongzihan1 小时前
LeetCode 283. 移动零:从辅助数组到双指针原地算法
c++·算法·leetcode
在所不辞兄1 小时前
【零基础学智能仿真-42】二维随机有限元实战——把随机材料场赋给网格单元
人工智能·深度学习·算法·机器学习·工程仿真