2021-06-11:给定两个字符串s1和s2,问s2最少删除多少字符可以成为s1的子串? 比如 s1 = “abcde“,s2 = “axbc“。
2021-06-11:给定两个字符串s1和s2,问s2最少删除多少字符可以成为s1的子串? 比如 s1 = “abcde”,s2 = “axbc”。
福大大 答案2021-06-11:
解法一
求出str2所有的子序列,然后按照长度排序,长度大的排在前面。
然后考察哪个子序列字符串和s1的某个子串相等(KMP),答案就出来了。
分析:
因为题目原本的样本数据中,有特别说明s2的长度很小。所以这么做也没有太大问题,也几乎不会超时。
但是如果某一次考试给定的s2长度远大于s1,这么做就不合适了。
str1长度为N,str2长度为M。时间复杂度:O(2的M次方*N)。
解法二
生成所有s1的子串
然后考察每个子串和s2的编辑距离(假设编辑距离只有删除动作且删除一个字符的代价为1)
如果s1的长度较小,s2长度较大,这个方法比较合适。
时间复杂度:O(N * M平方)。
代码用golang编写。代码如下:
package main
import (
"fmt"
"sort"
"strings"
)
func main() {
s1 := "abcde"
s2 := "axbc"
ret1 := minCost1(s1, s2)
ret3 := minCost3(s1, s2)
fmt.Println(ret1, ret3)
}
// 题目:
// 给定两个字符串s1和s2,问s2最少删除多少字符可以成为s1的子串?
// 比如 s1 = "abcde",s2 = "axbc"
// 返回 1
// 解法一
// 求出str2所有的子序列,然后按照长度排序,长度大的排在前面。
// 然后考察哪个子序列字符串和s1的某个子串相等(KMP),答案就出来了。
// 分析:
// 因为题目原本的样本数据中,有特别说明s2的长度很小。所以这么做也没有太大问题,也几乎不会超时。
// 但是如果某一次考试给定的s2长度远大于s1,这么做就不合适了。
func minCost1(s1 string, s2 string) int {
s2SubsVal := make([]string, 0)
s2Subs := &s2SubsVal
process(s2, 0, "", s2Subs)
//s2Subs.sort(new LenComp());
sort.Slice(*s2Subs, func(i, j int) bool {
return len((*s2Subs)[i]) > len((*s2Subs)[j])
})
for _, str := range *s2Subs {
if strings.Index(s1, str) != -1 { // indexOf底层和KMP算法代价几乎一样,也可以用KMP代替
return len(s2) - len(str)
}
}
return len(s2)
}
func process(str2 string, index int, path string, list *[]string) {
if index == len(str2) {
*list = append(*list, path)
return
}
process(str2, index+1, path, list)
pathbytes := []byte(path)
pathbytes = append(pathbytes, str2[index])
process(str2, index+1, string(pathbytes), list)
}
// 解法二的优化
func minCost3(s1 string, s2 string) int {
if len(s1) == 0 || len(s2) == 0 {
return len(s2)
}
M := len(s2)
N := len(s1)
dp := make([][]int, M)
for i := 0; i < M; i++ {
dp[i] = make([]int, N)
}
ans := M
for start := 0; start < N; start++ { // 开始的列数
if s2[0] != s1[start] {
dp[0][start] = M
}
for row := 1; row < M; row++ {
if s2[row] == s1[start] || dp[row-1][start] != M {
dp[row][start] = row
} else {
dp[row][start] = M
}
}
ans = getMin(ans, dp[M-1][start])
// 以上已经把start列,填好
// 以下要把dp[...][start+1....N-1]的信息填好
// start...end end - start +2
for end := start + 1; end < N && end-start < M; end++ {
// 0... first-1 行 不用管
first := end - start
if s2[first] == s1[end] && dp[first-1][end-1] == 0 {
} else {
dp[first][end] = M
}
for row := first + 1; row < M; row++ {
dp[row][end] = M
if dp[row-1][end] != M {
dp[row][end] = dp[row-1][end] + 1
}
if dp[row-1][end-1] != M && s2[row] == s1[end] {
dp[row][end] = getMin(dp[row][end], dp[row-1][end-1])
}
}
ans = getMin(ans, dp[M-1][end])
}
}
return ans
}
func getMin(a int, b int) int {
if a < b {
return a
} else {
return b
}
}
执行结果如下:

2021-06-11:给定两个字符串s1和s2,问s2最少删除多少字符可以成为s1的子串? 比如 s1 = “abcde“,s2 = “axbc“。的更多相关文章
- 给定两个字符串 s 和 t,它们只包含小写字母。 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。 请找出在 t 中被添加的字母。
给定两个字符串 s 和 t,它们只包含小写字母.字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母.请找出在 t 中被添加的字母. 示例: 输入: s = "abcd" ...
- 给定两个字符串,均只包含英文字母,需区分大小写,一个是源字符串SS(长度<1000), 另一个是目标字符串TS(长度<1000),请问能否通过删除SS中的字符(不改变顺序)将它变换成TS,如果可以输出“YES",不可以则输出“NO"。 输入说明:第一行为源字符串SS,第二行为目标字符串TS。
import java.util.Scanner;/* 给定两个字符串,均只包含英文字母,需区分大小写,一个是源字符串SS(长度<1000), 另一个是目标字符串TS(长度<1 ...
- [Swift]LeetCode712. 两个字符串的最小ASCII删除和 | Minimum ASCII Delete Sum for Two Strings
Given two strings s1, s2, find the lowest ASCII sum of deleted characters to make two strings equal. ...
- 【leet-code】712. 两个字符串的最小ASCII删除和
题目描述 给定两个字符串s1, s2,找到使两个字符串相等所需删除字符的ASCII值的最小和. 示例 1: 输入: s1 = "sea", s2 = "eat" ...
- poj 3415 后缀数组 两个字符串中长度不小于 k 的公共子串的个数
Common Substrings Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 11469 Accepted: 379 ...
- Q712 两个字符串的最小ASCII删除和
给定两个字符串s1, s2,找到使两个字符串相等所需删除字符的ASCII值的最小和. 示例 1: 输入: s1 = "sea", s2 = "eat" 输出: ...
- Python-求解两个字符串的最长公共子序列
一.问题描述 给定两个字符串,求解这两个字符串的最长公共子序列(Longest Common Sequence).比如字符串1:BDCABA:字符串2:ABCBDAB.则这两个字符串的最长公共子序列长 ...
- Leetcode之动态规划(DP)专题-712. 两个字符串的最小ASCII删除和(Minimum ASCII Delete Sum for Two Strings)
Leetcode之动态规划(DP)专题-712. 两个字符串的最小ASCII删除和(Minimum ASCII Delete Sum for Two Strings) 给定两个字符串s1, s2,找到 ...
- Java实现 LeetCode 712 两个字符串的最小ASCII删除和(最长公共子串&&ASCII值最小)
712. 两个字符串的最小ASCII删除和 给定两个字符串s1, s2,找到使两个字符串相等所需删除字符的ASCII值的最小和. 示例 1: 输入: s1 = "sea", s2 ...
- ✡ leetcode 161. One Edit Distance 判断两个字符串是否是一步变换 --------- java
Given two strings S and T, determine if they are both one edit distance apart. 给定两个字符串,判断他们是否是一步变换得到 ...
随机推荐
- 抽风的Maven、maven插件及配置
Idea 配合 Maven使用中有时遇到莫名奇妙的问题,又莫名奇妙的恢复正常.整理如下: 1.删除系统环境变量Maven_Home,只需在IDEA中指定Maven及settings.xml即可. 有时 ...
- 比 poi导入导出更好用的 EasyExcel使用小结
转载请注明出处: 官方文档: https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read 1.简洁 Java解析.生成E ...
- MySQL学习(九)frm与ibd了解
参考:https://cloud.tencent.com/developer/article/1533746 InnoDB: frm,ibd MyISAM: frm,myd,myi ibd是InnoD ...
- 来自我的Moments-实用学习资源或网站
目录 计算机基础知识 操作系统原理 计算机网络 其他 计算机技术栈 电子技术和嵌入式 计算机专业工作和面试 软件工程师手册(华为资料) 机器人工程师学习计划-硬核-知乎文章 提升效率的工具 BIT T ...
- DVWA-XSS(DOM)
漏洞详解. DOM XSS(Cross-site scripting)是一种Web安全漏洞,它利用了浏览器的DOM(文档对象模型)解析机制,通过注入恶意代码来攻击用户. DOM XSS与传统的反射型或 ...
- 最大流基础(Maximum Flow Basis)
1. 最大流问题定义 1.1 流网络(Flow network) Def. A flow network is a tuple \(G = (V, E, s, t, c)\): Digraph \(( ...
- Java面试——Redis
一.Redis 为什么那么快 [1]完全基于内存,绝大部分请求是纯粹的内存操作,非常快速.数据存在内存中.[2]数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的.[3]采用单线程 ...
- C# +SQL 存储过程 实现系统数据权限审查AOP效果
背景: 1.C/S系统架构 2.前端 Extjs 3.后台C# 4.数据库SQL 前端通过ajAx请求与后台通信. 前端应用页面统一继承入口类 BasePage 应用页面 public partia ...
- Win10系统总是锁屏关闭屏幕该怎么办?
Win10系统总是锁屏关闭屏幕该怎么办? 转目前发现最早之帖,自脚本之家:https://www.jb51.net/os/win10/398451.html 使用Win10系统很长时间了,最近发现 ...
- 一次因生产事故与chatGpt的对话
一次因生产事故与chatGpt的对话 前言:生产出现了一个内存溢出的事故,记录错误信息.错误日志如下 org.springframework.web.util.NestedServletExcepti ...