【leetcode】712. Minimum ASCII Delete Sum for Two Strings

本文探讨如何通过变式LCS问题解决LeetCode上关于两个字符串删除字符以求相同子串的最小ASCII码删除和。讲解了状态转移方程和关键代码实现,同时指出ASCII码最大公共子串不一定是最长的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/

题目大意:

分别在两个字符串s1、s2中删去一些字符,使得两个字符串剩余的子串相同。求删去的字符ASCII码数之和最小值。

解题方法:

这道题是LCS最长公共子串的变式,求删去字符ASCII码数之和最小,也就是求字符ASCII码之和最大的公共子串。

在LCS问题中,我们构建dp矩阵,行数为s1字符串长度+1,列数为s2字符串长度+1,dp[i][j]表示s1[:i] 与s2[:j]的最长公共子串长度,初始值全为零

状态转移方程:

1 如果s1[i]==s2[j] :dp[i][j]=dp[i-1][j-1]+1

2 如果s1[i]!=s2[j]:dp[i][j]=max(dp[i-1][j],dp[i][j-1])

 

MASCS:

dp[i][j]表示s1[:i] 与s2[:j]的字符ASCII码之和最大的公共子串ASCII码之和,初始值全为零

状态转移方程:

1 如果s1[i]==s2[j] :dp[i][j]=dp[i-1][j-1]+ord(s1[i])

2 如果s1[i]!=s2[j]:dp[i][j]=max(dp[i-1][j],dp[i][j-1])

python 代码:

class Solution(object):
    def minimumDeleteSum(self, s1, s2):
        """
        :type s1: str
        :type s2: str
        :rtype: int
        """
         
        dp = [[0]*(len(s2)+1) for _ in range(len(s1)+1)]
        
        for i in range(1,len(s1)+1):
            for j in range(1,len(s2)+1):
                if s1[i-1]==s2[j-1]:
                    dp[i][j]=dp[i-1][j-1]+ord(s1[i-1])
                else:
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1])
                    
        return sum(map(ord,s1+s2)) - dp[-1][-1]*2

sum函数:

sum(iterable) 返回可迭代对象中所有元素的和

map函数:

map(function, iterable, ...) 输入一个或者多个可迭代对象,返回一个新的列表,列表中第i个元素为function(iterable(i))的计算结果

ord函数:

ord(c)输入一个字符,输出这个字符的ASCII码值

疑问:

这里有一个问题:

ASCII码之和最大的公共子串是最长的公共子串吗?

答:不一定

可以通过

aa# #aa两个字符串进行举反例证明,这里假设ord(#)>2*ord(a)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值