最长公共子串(两种解法)

最长公共子串

题目描述

给定两个字符串str1和str2,输出两个字符串的最长公共子串,如果最长公共子串为空,输出-1。

示例1

输入

"1AB2345CD","12345EF"

返回值

"2345"

备注:

1 ≤∣str1∣,∣str2∣≤5000

代码如下:

import java.util.*;


public class Solution {
    /**
     * longest common substring
     * @param str1 string字符串 the string
     * @param str2 string字符串 the string
     * @return string字符串
     */
    //类似滑动窗口解法1
    public static String LCS (String str1, String str2) {
        // write code here
        StringBuilder sb = new StringBuilder();
        int end = 1;
        int start = 0;
        while (end < str1.length() + 1) {
            if (str2.contains(str1.substring(start,end))) {
                if (sb.length() < end-start) {
                    sb.delete(0,sb.length());
                    sb.append(str1,start,end);
                }
            }else {
                start++;
            }
            end++;
        }
        if (sb.length() == 0) {
            return "-1";
        }
        return sb.toString();
    }
    //动态规划 类似滑动窗口解法2
    public static String LCS2(String str1, String str2) {
        if (str1 == null || str2 == null) return "-1";
        int n1 = str1.length(), n2 = str2.length();
        if (n1 == 0 || n2 == 0) return "-1";
        int[][] dp = new int[n1 + 1][n2 + 1];

        int maxLen = 0, x = 0;
        for (int i = 1; i <= n1; i++) {
            char ch1 = str1.charAt(i - 1);
            for (int j = 1; j <= n2; j++) {
                char ch2 = str2.charAt(j - 1);
                if (ch1 == ch2) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                    if (dp[i][j] > maxLen) {
                        maxLen = dp[i][j];
                        x = i;
                    }
                }
            }
        }

        return maxLen == 0 ? "-1" : str1.substring(x - maxLen, x);
    }
}

解题思路:

​ 上面的代码类似滑动窗口,很好理解,就是头尾设置一个值,然后判断条件让start++和end++;第二个方法是看得别的大神的,解题思路值得我们思考!!!

### 关于第14届Python国赛中最长同类子串的相关题目与解题思路 在讨论第14届蓝桥杯国赛中涉及最长同类子串的题目之前,需先理解什么是“最长同类子串”。这类问题通常是指在一个给定字符串或数据集中查找具有某种特定属性的最大长度连续列。尽管引用材料未直接提及此具体竞赛题目[^4],但可以结合其他相关算法(如最长公共子串、无重复字符的最长子串以及动态规划方法)来推测可能的解法。 #### 可能的题目描述 假设比赛中有如下类似的题目:“给定一个由字母组成的字符串 `s`,找出其中最长的一段连续子串,使得该子串内的所有字符均相同。” #### 解题思路分析 以下是针对上述假设题目的一种通用解决方案: 1. **初始化变量** 定义两个变量:一个是用于记录当前正在处理的同类型子串长度 (`current_length`);另一个是全局最大长度 (`max_length`)。初始值均为零。 2. **遍历字符串** 使用单层循环逐一访问字符串中的每一个字符。如果当前字符与前一字符相等,则增加 `current_length` 值;否则重置它为 1 并重新计数新的潜在候选者。 3. **更新最大值** 每次迭代过程中都应比较并保存较大的那个数值到 `max_length` 中去。 下面给出一段基于以上逻辑编写的 Python 实现代码示例: ```python def longest_identical_substring(s): if not s: return 0 max_length = 1 current_length = 1 for i in range(1, len(s)): if s[i] == s[i - 1]: current_length += 1 max_length = max(max_length, current_length) else: current_length = 1 return max_length ``` 这段程的时间复杂度为 O(n),空间复杂度为 O(1)[^2],非常适合用来快速解决此类简单模式识别类的问题。 #### 结合已有知识点扩展思考 虽然本题较为基础,但它体现了几个重要概念的应用价值: - 类似滑动窗口技术的思想被广泛应用于各种字符串操作场景下优化性能表现; - 动态规划策略能够帮助我们更加系统化地拆分难题为目标函数形式表达的小规模实例组合关系; - 对数组索引边界条件的有效控制也是防止运行错误发生的重要环节之一。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值