java 求最长子串



@Test
public void work3()  throws Exception {
//3 获取两个字符串中最大相同子串。比如:
//   提示:将短的那个串进行长度依次递减的子串与较长的串比较。
String str1 = "abcwerthelloyuiodef";
String str2 = "cvhellobnm";
int maxLength = str2.length(); // 它相当于一把尺子, 用于在短串中截子串
// 总任务就是让最大长度趋于0
L1: while (maxLength > 0) {
// 每次总是以最大长度为长度, 从短串截取子串, 总是从0位置开始取, 取到右侧越界为止
for (int i = 0; i + maxLength <= str2.length(); i++) {
String child = str2.substring(i, i + maxLength);
//每次取到子串后, 在长串搜索一下子串, 如果搜索成功, 任务完成 
if (str1.indexOf(child) != -1) {
System.out.println(child);
break L1;
}
}
// 如果长度太长, 减短一下即可
maxLength--;
}
}


最长回文子串是字符处理中的经典问题,其目标是找出一个给定字符最长的回文子串。回文是指正向和反向读都相同的字符,例如 "aba" 或 "abba"。在 Java 中,解决这个问题有多种方法,其中常用的是**中心扩散法**和**动态规划法**。 ### 中心扩散法 中心扩散法的核心思想是:遍历每个字符,并以该字符为中心向两边扩展,检查是否是回文。由于回文可能是奇数长度或偶数长度,因此每次需要分别处理这两种情况。 以下是一个 Java 实现: ```java public class LongestPalindromicSubstring { public static String longestPalindrome(String s) { if (s == null || s.length() == 0) { return ""; } int start = 0; int maxLength = 1; for (int i = 0; i < s.length(); i++) { int len1 = expandAroundCenter(s, i, i); int len2 = expandAroundCenter(s, i, i + 1); int len = Math.max(len1, len2); if (len > maxLength) { maxLength = len; start = i - (maxLength - 1) / 2; } } return s.substring(start, start + maxLength); } private static int expandAroundCenter(String s, int left, int right) { while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) { left--; right++; } return right - left - 1; // 返回回文的长度 } public static void main(String[] args) { String input = "babad"; System.out.println("最长回文子串为:" + longestPalindrome(input)); } } ``` 这种方法的时间复杂度为 O(n²),空间复杂度为 O(1)。 ### 动态规划法 动态规划法的核心思想是使用一个二维数组 `dp[i][j]` 表示子串 `s[i...j]` 是否为回文。状态转移方程如下: - 如果 `s[i] == s[j]` 且 `j - i < 2`,那么 `dp[i][j] = true`。 - 如果 `s[i] == s[j]` 且 `dp[i+1][j-1]` 为 true,那么 `dp[i][j] = true`。 - 否则,`dp[i][j] = false`。 以下是一个 Java 实现: ```java public class LongestPalindromicSubstringDP { public static String longestPalindrome(String s) { int n = s.length(); boolean[][] dp = new boolean[n][n]; String result = ""; for (int j = 0; j < n; j++) { for (int i = 0; i <= j; i++) { if (i == j) { dp[i][j] = true; } else if (s.charAt(i) == s.charAt(j)) { if (j - i == 1) { dp[i][j] = true; } else { dp[i][j] = dp[i + 1][j - 1]; } } else { dp[i][j] = false; } if (dp[i][j] && j - i + 1 > result.length()) { result = s.substring(i, j + 1); } } } return result; } public static void main(String[] args) { String input = "cbbd"; System.out.println("最长回文子串为:" + longestPalindrome(input)); } } ``` 这种方法的时间复杂度为 O(n²),空间复杂度也为 O(n²)。 ### 总结 - **中心扩散法**是一种简单且高效的算法,适用于大多数情况。 - **动态规划法**虽然空间复杂度较高,但逻辑清晰,适合教学和理解。 两种方法都可以有效解决最长回文子串问题[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值