跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava算法

LeetCode 712. 两个字符串的最小 ASCII 删除和:状态压缩优化

介绍 LeetCode 712 题“两个字符串的最小 ASCII 删除和”的状态压缩解法。核心思路利用总和减去最大公共子序列权重的两倍来计算最小删除和。相比二维 DP,该方法使用一维数组配合 pre 变量暂存状态,将空间复杂度从 O(NM) 优化至 O(M)。代码采用 Java 实现,时间复杂度保持 O(NM)。

Elasticer发布于 2026/3/21更新于 2026/8/2354 浏览

整体思路

1. 核心问题与转换

这段代码依然沿用了 '总和 - 最大公共子序列(LCS)权重' 的逆向思维策略。 核心公式保持不变: 最小删除和 = ( s1 总和 + s2 总和 ) − ( LCS 字符 ASCII 和 × 2 )

2. 算法优化:状态压缩(1D DP)

与上一版二维数组解法不同,这里使用了一维数组进行空间优化。

  • 空间压缩原理: 在二维 DP 中,计算 dp[i][j] 只需要用到上一行的数据 dp[i-1][...] 和当前行左边的数据 dp[i][j-1]。
    • f[j+1] 在更新前,存储的是上一行对应位置的值(相当于 dp[i-1][j])。
    • f[j] 在更新后,存储的是当前行左边位置的值(相当于 dp[i][j-1])。
    • 难点:在于如何获取 dp[i-1][j-1](左上角的值)。因为在更新 f[j+1] 之前,f[j] 已经被更新为当前行的值了。
    • 解决方案:引入 pre 变量,专门用来暂存上一行对角线位置的值。
  • 逻辑流程:
    1. 初始化长度为 m + 1 的数组 f,初始全为 0(代表空串时的公共和)。
    2. 外层循环遍历 s1 的字符 x。
    3. 在内层循环开始前,初始化 pre = 0(代表第 0 列的左上角,即空前缀)。
    4. 内层循环遍历 s2 的索引 j:
      • 先用 temp 保存 f[j+1] 的旧值(即下一轮需要的左上角值)。
      • 根据 x 和 t[j] 是否相等,利用 pre、f[j+1](旧)、f[j](新)更新 f[j+1]。
      • 更新 pre = temp,为下一个位置做准备。

完整代码

class Solution {
    public int minimumDeleteSum(String s1, String s2) {
        // 1. 计算两字符串初始的总 ASCII 和
        int sum = s1.chars().sum() + s2.chars().sum();
        char[] s = s1.toCharArray();
        char[] t = s2.toCharArray();
        int m = t.length;
        // 2. 创建一维 DP 数组
        // f[k] 表示 s1 当前处理到的前缀与 s2 的前 k 个字符的最大公共 ASCII 权重和
        int[] f = new int[m + 1];
        // Java 中 int 数组默认初始化为 0,符合逻辑(空串的公共和为 0)
        // 外层循环:遍历 s1 的每个字符 x
        for (char x : s) {
            // pre 用于维护 "左上角" (diagonal) 的状态
            // 相当于二维 DP 中的 dp[i-1][j-1]
            // 对于每一行的第一个元素,其左上角是 f[0],始终为 0
            int pre = 0;
            // 内层循环:遍历 s2 的每个位置 j
            for (int j = 0; j < m; j++) {
                // temp 暂存 f[j+1] 在更新前的值
                // 这个值对应二维 DP 中的 dp[i-1][j] (上一行的值)
                // 在下一次循环 (j+1) 时,它将变成 "左上角" (pre)
                int temp = f[j + 1];
                // 状态转移逻辑
                if (x == t[j]) {
                    // 字符匹配:
                    // 当前值 = 左上角值 (pre) + 当前字符 ASCII * 2
                    f[j + 1] = pre + x * 2;
                } else {
                    // 字符不匹配:
                    // 取 "上方" (f[j+1] 旧值) 和 "左方" (f[j] 新值) 的最大值
                    f[j + 1] = Math.max(f[j + 1], f[j]);
                }
                // 更新 pre,将当前的旧值传递给下一次内层循环作为左上角使用
                pre = temp;
            }
        }
        // 3. 计算结果
        // 总和 - 最大保留部分的和
        return sum - f[m];
    }
}

时空复杂度

1. 时间复杂度:O(N \times M)
  • 计算依据:
    • 双重循环结构没有改变。
    • 外层循环执行 N 次(s1 的长度),内层循环执行 M 次(s2 的长度)。
    • 内部操作均为 O(1)。
  • 结论:O(N \times M)。
2. 空间复杂度:O(M)
  • 计算依据:
    • 这是此代码的主要亮点。
    • 我们将原本 (N + 1) × (M + 1) 的二维数组压缩为了长度为 M + 1 的一维数组 f。
    • 额外使用了几个常数变量(pre, temp 等)。
    • 空间消耗仅与 s2 的长度线性相关。
  • 结论:O(M),其中 M 是 s2 的长度。
    • 优化提示:如果 N < M,可以在代码开始前交换 s1 和 s2,使空间复杂度进一步优化为 O(min(N, M))。

目录

  1. 整体思路
  2. 1\. 核心问题与转换
  3. 2\. 算法优化:状态压缩(1D DP)
  4. 完整代码
  5. 时空复杂度
  6. 1\. 时间复杂度:O(N \times M)
  7. 2\. 空间复杂度:O(M)
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • SpringAI ChatClient、记忆与 RAG 应用实践
  • Llama-Factory 模型评估模块详解:BLEU、ROUGE、Accuracy 全支持
  • YOLO26-Pose 零样本姿态估计:从原理到机器人应用
  • Java 流程控制:从条件判断到循环遍历
  • C++ 类和对象(中):默认成员函数详解
  • Dify 快速部署与 Docker 国内镜像切换教程
  • C++二叉搜索树:从插入到删除,以及Key/Value模型实现
  • C++ 类型转换:从基础到四种核心强制转换方式
  • HTTP 应用层协议详解
  • DSO.ai:Synopsys 基于 AI 的搜索优化型 EDA 工具解析
  • Python 自动化测试入门:编写与运行测试用例
  • AiNiee 桌面 AI 翻译工具功能详解与快速上手
  • C++26 模块化编程与 MSVC 支持特性解析
  • 微信小程序校园失物招领系统(SpringBoot 后端+Vue 管理端)
  • Flutter mediapipe_core 鸿蒙化适配指南:端侧 AI 推理与视觉任务集成
  • Gazebo 机器人三维物理仿真平台
  • C++ 火柴人跑酷游戏开发流程详解
  • LangChain 入门:Memory 记忆组件详解
  • 8 篇必读的大模型论文精选
  • Pi0 机器人 VLA 大模型在昇腾 A2 平台上的测评

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online