求公共子字符串问题(连续的)

这个题目是当时远景能源公司现场笔试的一道题目,当时根本就不知道动态规划是什么鬼,直接上来就暴力求解,面试官很谄媚的问我,你这能求出来吗?当时很年轻的说,能啊!现在想,当时哪来的自信和逗比勇气说这大话。。。在《进军硅谷》这本书上看到原题,我是懵逼,怎么想出这种解答出来的,下面直接上思路和代码。

思路:

定义二维数组dp[i][j]记录最大公共子串的长度,

  • 若要返回字符串可以用s1.substring(i-dp[i][j]+1, i+1)
  • 当s[i]==s[j]时,dp[i][j]=dp[i-1][j-1]+1;
  • 当s[i]!=s[j]时,dp[i][j]=0;

有点类似于数学归纳法

方案:

  • 首先考虑空或者长度为0的情况,直接返回"";
  • 然后进入双重循环:
  • 1.利用charAt(int index)方法来比较两个字符串相等的时机
  • 2.考虑边界情况,两个字符串中有一个是起始为0就相等,则dp[i][j]=1
  • 3.除了边界情况,其他最大字符串长度为dp[i][j]=dp[i-1][j-1]+1;
  • 4.不断的替换掉最大的长度并返回公共子串
  • 最后循环结束后,返回最大的公共子串
     public static String maxCommonString(String s1, String s2) {
String res = "";
if (s1 == null || s1.length() == 0 || s2 == null || s2.length() == 0)
return res;
int max = 0, m = s1.length(), n = s2.length();
int[][] dp = new int[m][n]; // 定义一个二维数组记录最大公共子串的长度
// 计算到s1的第i个字符和s2的第j个字符为止的最大公共子串长度
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
// 如果s1字符串在i处和s2字符串在j处有字符相同,进入if代码块中
if (s1.charAt(i) == s2.charAt(j)) {
if (i == 0 || j == 0)
dp[i][j] = 1;// 边界的情况
else
dp[i][j] = dp[i - 1][j - 1] + 1;// 加上当前长度
// 记录最大长度和子串
if (dp[i][j] > max) {
max = dp[i][j];
res = s1.substring(i - dp[i][j] + 1, i + 1);// substring()左闭右开
}
}
}
}
return res;
}

动态规划介绍

动态规划算法一般是基于一个递推公式(如上面的当s[i]==s[j]时,dp[i][j]=dp[i-1][j-1]+1;)以及一个或多个初始状态(当s[i]!=s[j]时,dp[i][j]=0;),当前子问题其实是由上一次子问题的解推算出来的。
【附带福利:markdown每行缩进的方式】

半方的空白&ensp;或&#8194;
全方的空白&emsp;或&#8195;
不断行的空白格&nbsp;或&#160;
(分号都是英文格式的)

动态规划:给出两个字符串s1和s2,返回其中最大的公共子串的更多相关文章

  1. Java算法——求出两个字符串的最长公共字符串

    问题:有两个字符串str1和str2,求出两个字符串中最长公共字符串. 例如:“acbbsdef”和"abbsced"的最长公共字符串是“bbs” 算法思路: 1.把两个字符串分别 ...

  2. C语言:求n(n<10000)以内的所有四叶玫瑰数。-将字符串s1和s2合并形成新的字符串s3,先取出1的第一个字符放入3,再取出2的第一个字符放入3,

    //函数fun功能:求n(n<10000)以内的所有四叶玫瑰数并逐个存放到result所指数组中,个数作为返回值.如果一个4位整数等于其各个位数字的4次方之和,则称该数为函数返回值. #incl ...

  3. [华为]查找两个字符串a,b中的最长公共子

    链接:https://www.nowcoder.com/questionTerminal/181a1a71c7574266ad07f9739f791506来源:牛客网 查找两个字符串a,b中的最长公共 ...

  4. Java实现 LeetCode 583 两个字符串的删除操作(求最长公共子序列问题)

    583. 两个字符串的删除操作 给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符. 示例: 输入: " ...

  5. 389. Find the Difference 找出两个字符串中多余的一个字符

    [抄题]: Given two strings s and t which consist of only lowercase letters. String t is generated by ra ...

  6. js判断出两个字符串最大子串的函数

    <!DOCTYPE html><html><head> <title></title></head><script typ ...

  7. poj 2774 后缀数组 两个字符串的最长公共子串

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 31904   Accepted: 12 ...

  8. 动态规划 最长公共子序列 LCS,最长单独递增子序列,最长公共子串

    LCS:给出两个序列S1和S2,求出的这两个序列的最大公共部分S3就是就是S1和S2的最长公共子序列了.公共部分 必须是以相同的顺序出现,但是不必要是连续的. 选出最长公共子序列.对于长度为n的序列, ...

  9. Leetcode之动态规划(DP)专题-712. 两个字符串的最小ASCII删除和(Minimum ASCII Delete Sum for Two Strings)

    Leetcode之动态规划(DP)专题-712. 两个字符串的最小ASCII删除和(Minimum ASCII Delete Sum for Two Strings) 给定两个字符串s1, s2,找到 ...

随机推荐

  1. Android进阶(三)android httpClient 支持HTTPS的访问方式

    项目中Android https请求地址遇到了这个异常(无终端认证): javax.net.ssl.SSLPeerUnverifiedException: No peer certificate 是S ...

  2. 1034. Head of a Gang (30) -string离散化 -map应用 -并查集

    题目如下: One way that the police finds the head of a gang is to check people's phone calls. If there is ...

  3. 基于java自身技术实现消息方式的系统间通信

    这篇博客基本照搬了分布式java应用基础与实践一书的内容 java自带的远程调用分两种一种是rmi,一种是webservice 我们先看rmi(remote method invoke)# 使用rmi ...

  4. 调试bootmgr&winload vista&win7 x86&x64

    设置调试bootmgr 1.以管理员权限运行cmd.exe 2.执行以下命令 3.  参照我的另一篇文章<win8 + vmware + windbg 双机调试 >中的第1.3步,建立wi ...

  5. 解决 RtlCreateActivationContext() failed 0xc000000d

    gtest 示例的Debug版启动报错: Debug输出如下: 'sample1_unittest.exe': Loaded 'D:\LibSrc\gtest_1.7.0_build\Debug\sa ...

  6. AngularJS进阶(二十五)requirejs + angular + angular-route 浅谈HTML5单页面架构

    requirejs + angular + angular-route 浅谈HTML5单页面架构 众所周知,现在移动Webapp越来越多,例如天猫.京东.国美这些都是很好的例子.而在Webapp中,又 ...

  7. VS2012 发布网站步骤

    VS2012中发布网站的方式与以往有了不同,前面的版本发布如图 而2012点publish的时候弹出框有所不同,这边需要新建一个profile名字随便起,发布的方式有好几种, 当然不同的方式配置不同, ...

  8. (NO.00001)iOS游戏SpeedBoy Lite成形记(四)

    下面我们来实现选手从起点开始移动到终点的代码. 首先在GameScene.h接口中添加matchRun方法: #import "CCNode.h" @interface GameS ...

  9. Java进阶(七)Java加密技术之非对称加密算法RSA

    Java加密技术(四)--非对称加密算法RSA 非对称加密算法--RSA 基本概念 非对称加密算法是一种密钥的保密方法. 非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(priv ...

  10. Android存储系统的架构与设计

    一.概述 本文讲述Android存储系统的架构与设计,基于Android 6.0的源码,涉及到最为核心的便是MountService和Vold这两个模块以及之间的交互.为了缩减篇幅,只展示部分核心代码 ...