AcWing 902. 关于只操作最后一个字符的思考
原题链接
简单
作者:
lencit
,
2023-12-01 18:07:00
,
所有人可见
,
阅读 44
假设第一个序列长度固定
随着j往后面走,第二个序列每次逐步放出来一个新的字符
所有字符匹配的表要条件是最后一个字母相同
因此分为两大类,这样解决了困惑我很久的为什么只能对最后一个字符操作的疑惑
1.用现在第一个序列的最后一个字符匹配第二个序列刚放出来的字符(这两个字符得形同才行) f[i-1][j-1]
2.不用现在第一个序列的最后一个字符匹配第二个序列刚放出来的字符
(1)删 :只有删最后一个字符才能改变第一个字符的最后一个字符,才能达到不用现在的最后一个字符与刚放出来的字符匹配的目的 f[i-1][j-1]+1
(2)换 :只有替换最后一个字符才能改变第一个字符的最后一个字符,才能达到不用现在的最后一个字符与刚放出来的字符匹配的目的 f[i-1][j]+1
(3)增 :只有替换最后一个字符才能改变第一个字符的最后一个字符,才能达到不用现在的最后一个字符与刚放出来的字符匹配的目的 f[i][j-1]+1
接着循环i,j即可退出答案
边界:f[i][0]=i;//只能删
f[0][i]=i;//只能加
最后附上代码
import java.util.*;
public class Main{
static String s1=" ";
static String s2=" ";
static int N=2010;
static int inf=0x3f3f3f3f;
static int [][] f=new int[N][N];
public static void main(String[] args){
Scanner scan=new Scanner(System.in);
s1+=scan.nextLine();
s2+=scan.nextLine();
int n=s1.length();
int m=s2.length();
for (int i=0;i<N;i++) Arrays.fill(f[i],inf);
f[0][0]=0;
for (int i=0;i<N;i++) {
f[0][i]=i;
f[i][0]=i;
}
for (int i=1;i<n;i++){
for (int j=1;j<m;j++){
f[i][j]=Math.min(f[i-1][j]+1,Math.min(f[i][j-1]+1,f[i-1][j-1]+1));
if (s1.charAt(i)==s2.charAt(j)) f[i][j]=Math.min(f[i][j],f[i-1][j-1]);
}
}
System.out.println(f[n-1][m-1]);
}
}