【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)。
相关推荐
茉莉玫瑰花茶5 小时前
C++ 17 详细特性解析(5)
开发语言·c++·算法
cpp_25015 小时前
P10570 [JRKSJ R8] 网球
数据结构·c++·算法·题解
cpp_25015 小时前
P8377 [PFOI Round1] 暴龙的火锅
数据结构·c++·算法·题解·洛谷
uesowys5 小时前
Apache Spark算法开发指导-Factorization machines classifier
人工智能·算法
TracyCoder1235 小时前
LeetCode Hot100(26/100)——24. 两两交换链表中的节点
leetcode·链表
季明洵6 小时前
C语言实现单链表
c语言·开发语言·数据结构·算法·链表
shandianchengzi6 小时前
【小白向】错位排列|图文解释公考常见题目错位排列的递推式Dn=(n-1)(Dn-2+Dn-1)推导方式
笔记·算法·公考·递推·排列·考公
I_LPL6 小时前
day26 代码随想录算法训练营 回溯专题5
算法·回溯·hot100·求职面试·n皇后·解数独
Yeats_Liao6 小时前
评估体系构建:基于自动化指标与人工打分的双重验证
运维·人工智能·深度学习·算法·机器学习·自动化