最长公共子串(动态规划)

这篇具有很好参考价值的文章主要介绍了最长公共子串(动态规划)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

查找两个字符串a,b中的最长公共子串_牛客题霸_牛客网

1.找a 和 b 的最长公共子串实际上是在a的子串和b的子串中找最长公共子串

ins[i][j]实际上记录的就是 以a的第i个字符和以b的第j个字符结尾的子串中存在的最长公共子串的长度

接下来我们举个例子:

a: abcabcde

b: abcd

ins[1][1] = 'a'  'a'  --> 'a'  1 

ins[2][2] = 'ab'  'ab' --> 'ab'  2

ins[3][3] = 'abc' 'abc' --> 'abc' 3

ins[4][4] = 'abca' 'abcd' --> 0

到了ins[4][4] 的我卡住了,当时想的是ins[4][4] 就是a的子串 abca  b的子串abcd中存在的最长公共子串应该是abc 那么这个值是3 而不是0

我们先跳过一下:找一下这个整体规律:

如果以第i个字符结尾的字符和以第j个字符结尾的字符相等,那么

ins[i][j] = ins[i-1][j-1] + 1  (很明显前面三个都是满足的)

假如不相等,ins[i][j] = 0

但是为什么不是 ins[i][j] = ins[i-1][j-1]

接下来分析一下:实际上按照ins[4][4] = ins[3][3] = 3的说法是不完全准确的,为什么?

假设哈: a = abcdh

             b = abcjh

ins[3][3] = 3

这里用假设性原则:ins[i][j] = ins[i-1][j-1]

ins[4][4] = ins[3][3] = 3

ins[5][5] = ins[4][4] +1 = 4

实际上呢??? ins[5][5] 的最常公共子串长度是3 ,这个我们一样就可以看出来,那么按照我们那种假设性原则导致了变成了求最长公共子序列的问题(也就是不连续即可)

除非你能保证你i j 不相等且是最后一个的时候才能说明 ins[i][j] = in[i-1][j-1],但是之前的是不行的

所以这个地方着重解释了当两个字符不相等的时候为什么不是ins[i][j] = ins[i-1][j-1] 

2.那么ins[i][j] != ins[i-1][j-1] 究竟结果是啥呢??? 实际上这里你可以设置为0

因为你设置成0不影响结果得,你之前的ins[3][3] = 3实际上是把这个最长子串的长度记录下来了,不必去在ins[4][4] 里搅混水

当我们去遍历这个二维数组的时候,一定是记录下了这个最长子串,当你再去更新的时候就行

3.那么这个起始位置如何判断???

start = i - max, 我们是从短字符串来判定的, 你确定了这个最长子串,肯定是最后一个位置是

i  而且你的最后一个字符相等说明 i之前的max个字符都相等,那么从 (i - max,i)就是最长子串文章来源地址https://www.toymoban.com/news/detail-411095.html

import java.io.*;
import java.util.*;
public class Main{
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while((str = br.readLine())!=null){
            String ss = br.readLine();
            if(str.length()<ss.length()){
                System.out.println(res(str,ss));
            }else{
                System.out.println(res(ss,str));
            }
        }
    }
    public static String res(String s,String c){
        char[] ch1 = s.toCharArray();
        char[] ch2 = c.toCharArray();
        int[][] ins = new int[ch1.length + 1][ch2.length + 1];
        int max = 0;
        int start = 0;
        for (int i = 1; i < ch1.length; i++) {
            for (int j = 1; j < ch2.length; j++) {
                if(ch1[i-1]==ch2[j-1]){
                    ins[i][j] = ins[i-1][j-1]+1;
                    if(ins[i][j]>max){
                        max = ins[i][j];
                        start = i-max;
                    }
                }
            }
        }
        return s.substring(start,start+max);
    }
}

到了这里,关于最长公共子串(动态规划)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 两个数组的动态规划——最长公共子序列模型

    1.考虑空串,即dp表多出一行一列, 代表某个字符串为空。 2.考虑最后一个位置;是否相等; 3.可在字符串最前面加虚拟位置以对应映射关系; 4.一般横行是j,列是i。此时第一行代表第二个字符串不为空,即第一个字符串是空的 给你两个字符串  s   和  t  ,统计并返回在

    2024年03月10日
    浏览(58)
  • 剑指offer(C++)-JZ48:最长不含重复字符的子字符串(算法-动态规划)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。 数据范围:  s.length≤40000 s.length≤40000 示例: 输入: 返回值: 说明

    2024年02月06日
    浏览(42)
  • (动态规划) 剑指 Offer 48. 最长不含重复字符的子字符串 ——【Leetcode每日一题】

    难度:中等 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。 示例 1: 输入: “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 示例 2: 输入: “bbbbb” 输出: 1 解释: 因为无重复字符的最长子串是 “b”,所

    2024年02月11日
    浏览(45)
  • 动态规划学习——最长回文子序列,让字符串变成回文串的最小插入次数

    1.题目 给你一个字符串  s  ,找出其中最长的回文子序列,并返回该序列的长度。 子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。 示例 1: 示例 2: 提示: 1 = s.length = 1000 s  仅由小写英文字母组成 2.题目接口  3.解题思路

    2024年02月04日
    浏览(42)
  • 动态规划16 | ● 583. 两个字符串的删除操作 ● *72. 编辑距离

    https://programmercarl.com/0583.%E4%B8%A4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%88%A0%E9%99%A4%E6%93%8D%E4%BD%9C.html 考点 子序列问题 我的思路 dp[i][j]的含义是,当两个字符串分别取前i和j个元素时,对应的最少相等删除步数是多少 递推公式为,如果两个字符串第i和j个元素恰好相等,则dp值应

    2024年04月22日
    浏览(35)
  • 动态规划-最长回文子串

    突然觉得很有必要将学过的内容记录下来,这样后续在需要用到的时候就可以避免从头进行学习,而去看自己之前做过的笔记无疑是效率更高的方法。 而作为计算机专业的学生,纸质笔记无法很好的进行记录,像写代码、画图、画表都是很麻烦的,而且纸质的很容易丢,因此

    2024年04月14日
    浏览(29)
  • 动态规划——最长回文子串

    给你一个字符串 s ,找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。 示例 1: 示例 2: 1、动态规划算法 解题思路 (1)考虑 回文串的性质 :若一个子串是回文串并且 长度大于2 ,则将其 首尾两个字母去除 后,该子串仍然是一

    2024年04月08日
    浏览(40)
  • LeetCode | C++ 动态规划——583. 两个字符串的删除操作、72. 编辑距离

    583题目链接 做法一: 本题和1143.最长公共子序列基本相同,只要求出两个字符串的最长公共子序列长度即可,那么除了最长公共子序列之外的字符都是必须删除的,最后用两个字符串的总长度减去两个最长公共子序列的长度就是删除的最少步数。 做法二: 本题和115.不同的子

    2024年02月16日
    浏览(41)
  • 【字符串 简单】LeetCode 14. 最长公共前缀 Java

    我的思路: 给字符串数组按照字符串的长度从长到短排序,因为最长公共前缀最长的话,也只能是字符串数组中最短的那一个字符串 设置一个index变量,表示当前正在检查字符数组中所有字符串的index位置 循环遍历字符串数组n遍,n也就是最长公共前缀的长度 其他思路,方法

    2024年02月15日
    浏览(32)
  • 264.【华为OD机试真题】最长子字符串的长度(二)(动态规划DP-Java&Python&C++&JS实现)

    🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(JavaPythonC++JS分别实现),详细代码讲解,助你深入学习,深度掌握!

    2024年02月20日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包