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. 给定两个字符串,判断他们是否是一步变换得到 ...
随机推荐
- Visual Studio-截断类错误
Visual Studio-截断类错误 传输数据的目标端,将提示的错误的表对应的截断字段的长度增大,重新创建表 并且,对于Visual 传输节点里面,双击红色报错的节点,然后对于数据源右键,接着选择& ...
- 【Airtest相关】收集一些Airtest的介绍
1.项目简介 ui自动化一直是个让人头疼的事,主要是因为系统兼容性难度较大和开发维护成本比较高, 以前使用过appium,通用性比较差,并且开发有一定的基础才行,更难以忍受的是后期的维护成本:然后接触 ...
- python之序列化与反序列化
#!/usr/bin/env python# -*- coding:utf-8 -*-#Author:QiFeng Zhang'''序列化反序列化之json应用'''import json #导入js ...
- win10_pyhive链接hive失败,提示:Could not start SASL
win10_pyhive链接hive失败,提示:Could not start SASL https://blog.csdn.net/weixin_45684985/article/details/1 ...
- 【LeetCode动态规划#05】背包问题的理论分析(基于代码随想录的个人理解,多图)
背包问题 问题描述 背包问题是一系列问题的统称,具体包括:01背包.完全背包.多重背包.分组背包等(仅需掌握前两种,后面的为竞赛级题目) 下面来研究01背包 实际上即使是最经典的01背包,也不会直接出 ...
- Ansible 安装并简单使用
Ansible 简介 Ansible 是一款 IT 自动化工具.主要应用场景有配置系统.软件部署.持续发布及不停服平滑滚动更新的高级任务编排. Ansible 本身非常简单易用,同时注重安全和可靠性, ...
- .Net Core工作流WorkFlowCore
前言 WorkFlowCore是一个针对.NetCore的轻量级的工作流引擎,提供了FluentAPI.多任务.持久化以及并行处理的功能,适合于小型工作流.责任链的需求开发.支持工作流长期运行,提供了 ...
- ChatGPT研究报告:AIGC带来新一轮范式转移
以ChatGPT为代表的AIGC(人工智能生成内容)将成为新一轮范式转移的开始. 本文约4000字,目标是快速建立AIGC知识体系,含有大量的计算专业名词,建议阅读同时扩展搜索. 一.行业现状 1.概 ...
- YII2.0的文件上传, 并把文件名称重新编译
/** *@Action 文件上传示例 *@这里我们演示的是一个YII2.0的文件上传, 并把文件名称重新编译 *@我们上传的是一个叫 photo 的jpg和png格式的文件 */ Controlle ...
- 【Zookeeper】(一)概述与内部原理
Zookeeper概述 1 概述 Zookeeper是一个开源的.分布式的,为分布式应用提供协调服务的Apache项目. Zookeeper从设计模式的角度来看,是一个基于观察者模式设计的分布式服务管 ...